Fix undefined function pointer casts in {d2i,i2d}_Foo_{bio,fp}

Lacking C++, this instead adds a mess of macros. With this done, all the
function-pointer-munging "_of" macros in asn1.h can also be removed.

Update-Note: A number of *really* old and unused ASN.1 macros were
removed.

Bug: chromium:785442
Change-Id: Iab260d114c7d8cdf0429759e714d91ce3f3c04b2
Reviewed-on: https://boringssl-review.googlesource.com/32106
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: Adam Langley <alangley@gmail.com>
This commit is contained in:
David Benjamin 2018-09-22 19:35:12 -05:00 committed by Adam Langley
parent 217bfd3c96
commit 419144adce
12 changed files with 151 additions and 613 deletions

View File

@ -58,66 +58,24 @@
#include <limits.h> #include <limits.h>
#include <openssl/buf.h> #include <openssl/bio.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/mem.h> #include <openssl/mem.h>
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
#ifndef NO_OLD_ASN1
# ifndef OPENSSL_NO_FP_API
void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x)
{
BIO *b = BIO_new_fp(in, BIO_NOCLOSE);
if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return NULL;
}
void *ret = ASN1_d2i_bio(xnew, d2i, b, x);
BIO_free(b);
return (ret);
}
# endif
void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x)
{
BUF_MEM *b = NULL;
const unsigned char *p;
void *ret = NULL;
int len;
len = asn1_d2i_read_bio(in, &b);
if (len < 0)
goto err;
p = (unsigned char *)b->data;
ret = d2i(x, &p, len);
err:
if (b != NULL)
BUF_MEM_free(b);
return (ret);
}
#endif
void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
{ {
BUF_MEM *b = NULL; uint8_t *data;
const unsigned char *p; size_t len;
void *ret = NULL; // Historically, this function did not impose a limit in OpenSSL and is used
int len; // to read CRLs, so we leave this without an external bound.
if (!BIO_read_asn1(in, &data, &len, INT_MAX)) {
len = asn1_d2i_read_bio(in, &b); return NULL;
if (len < 0) }
goto err; const uint8_t *ptr = data;
void *ret = ASN1_item_d2i(x, &ptr, len, it);
p = (const unsigned char *)b->data; OPENSSL_free(data);
ret = ASN1_item_d2i(x, &p, len, it); return ret;
err:
if (b != NULL)
BUF_MEM_free(b);
return (ret);
} }
#ifndef OPENSSL_NO_FP_API #ifndef OPENSSL_NO_FP_API
@ -133,158 +91,3 @@ void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
return ret; return ret;
} }
#endif #endif
typedef struct asn1_const_ctx_st
{
const unsigned char *p;/* work char pointer */
int eos; /* end of sequence read for indefinite encoding */
int error; /* error code to use when returning an error */
int inf; /* constructed if 0x20, indefinite is 0x21 */
int tag; /* tag from last 'get object' */
int xclass; /* class from last 'get object' */
long slen; /* length of last 'get object' */
const unsigned char *max; /* largest value of p allowed */
const unsigned char *q;/* temporary variable */
const unsigned char **pp;/* variable */
int line; /* used in error processing */
} ASN1_const_CTX;
#define HEADER_SIZE 8
#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{
BUF_MEM *b;
unsigned char *p;
int i;
ASN1_const_CTX c;
size_t want = HEADER_SIZE;
int eos = 0;
size_t off = 0;
size_t len = 0;
b = BUF_MEM_new();
if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
ERR_clear_error();
for (;;) {
if (want >= (len - off)) {
want -= (len - off);
if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
i = BIO_read(in, &(b->data[len]), want);
if ((i < 0) && ((len - off) == 0)) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
if (i > 0) {
if (len + i < len) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
len += i;
}
}
/* else data already loaded */
p = (unsigned char *)&(b->data[off]);
c.p = p;
c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag), &(c.xclass),
len - off);
if (c.inf & 0x80) {
uint32_t error = ERR_peek_error();
if (ERR_GET_LIB(error) != ERR_LIB_ASN1 ||
ERR_GET_REASON(error) != ASN1_R_TOO_LONG) {
goto err;
}
ERR_clear_error();
}
i = c.p - p; /* header length */
off += i; /* end of data */
if (c.inf & 1) {
/* no data body so go round again */
eos++;
if (eos < 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
goto err;
}
want = HEADER_SIZE;
} else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) {
/* eos value, so go back and read another header */
eos--;
if (eos <= 0)
break;
else
want = HEADER_SIZE;
} else {
/* suck in c.slen bytes of data */
want = c.slen;
if (want > (len - off)) {
size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
want -= (len - off);
if (want > INT_MAX /* BIO_read takes an int length */ ||
len + want < len) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
while (want > 0) {
/*
* Read content in chunks of increasing size
* so we can return an error for EOF without
* having to allocate the entire content length
* in one go.
*/
size_t chunk = want > chunk_max ? chunk_max : want;
if (!BUF_MEM_grow_clean(b, len + chunk)) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
want -= chunk;
while (chunk > 0) {
i = BIO_read(in, &(b->data[len]), chunk);
if (i <= 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
/*
* This can't overflow because |len+want| didn't
* overflow.
*/
len += i;
chunk -= i;
}
if (chunk_max < INT_MAX/2)
chunk_max *= 2;
}
}
if (off + c.slen < off) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
off += c.slen;
if (eos <= 0) {
break;
} else
want = HEADER_SIZE;
}
}
if (off > INT_MAX) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
*pb = b;
return off;
err:
if (b != NULL)
BUF_MEM_free(b);
return -1;
}

View File

@ -59,30 +59,6 @@
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/mem.h> #include <openssl/mem.h>
void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
{
unsigned char *b, *p;
const unsigned char *p2;
int i;
char *ret;
if (x == NULL)
return (NULL);
i = i2d(x, NULL);
b = OPENSSL_malloc(i + 10);
if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return (NULL);
}
p = b;
i = i2d(x, &p);
p2 = b;
ret = d2i(NULL, &p2, i);
OPENSSL_free(b);
return (ret);
}
/* /*
* ASN1_ITEM version of dup: this follows the model above except we don't * ASN1_ITEM version of dup: this follows the model above except we don't
* need to allocate the buffer. At some point this could be rewritten to * need to allocate the buffer. At some point this could be rewritten to

View File

@ -56,54 +56,10 @@
#include <openssl/asn1.h> #include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/mem.h> #include <openssl/mem.h>
int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
{
BIO *b = BIO_new_fp(out, BIO_NOCLOSE);
if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return 0;
}
int ret = ASN1_i2d_bio(i2d, b, x);
BIO_free(b);
return ret;
}
int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *x)
{
char *b;
unsigned char *p;
int i, j = 0, n, ret = 1;
n = i2d(x, NULL);
if (n <= 0)
return 0;
b = (char *)OPENSSL_malloc(n);
if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return (0);
}
p = (unsigned char *)b;
i2d(x, &p);
for (;;) {
i = BIO_write(out, &(b[j]), n);
if (i == n)
break;
if (i <= 0) {
ret = 0;
break;
}
j += i;
n -= i;
}
OPENSSL_free(b);
return (ret);
}
int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
{ {
@ -120,25 +76,13 @@ int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
{ {
unsigned char *b = NULL; unsigned char *b = NULL;
int i, j = 0, n, ret = 1; int n = ASN1_item_i2d(x, &b, it);
n = ASN1_item_i2d(x, &b, it);
if (b == NULL) { if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return (0); return 0;
} }
for (;;) { int ret = BIO_write_all(out, b, n);
i = BIO_write(out, &(b[j]), n);
if (i == n)
break;
if (i <= 0) {
ret = 0;
break;
}
j += i;
n -= i;
}
OPENSSL_free(b); OPENSSL_free(b);
return (ret); return ret;
} }

View File

@ -177,6 +177,19 @@ int BIO_write(BIO *bio, const void *in, int inl) {
return ret; return ret;
} }
int BIO_write_all(BIO *bio, const void *data, size_t len) {
const uint8_t *data_u8 = data;
while (len > 0) {
int ret = BIO_write(bio, data_u8, len > INT_MAX ? INT_MAX : (int)len);
if (ret <= 0) {
return 0;
}
data_u8 += ret;
len -= ret;
}
return 1;
}
int BIO_puts(BIO *bio, const char *in) { int BIO_puts(BIO *bio, const char *in) {
return BIO_write(bio, in, strlen(in)); return BIO_write(bio, in, strlen(in));
} }

View File

@ -333,17 +333,7 @@ int i2d_PKCS7(const PKCS7 *p7, uint8_t **out) {
} }
int i2d_PKCS7_bio(BIO *bio, const PKCS7 *p7) { int i2d_PKCS7_bio(BIO *bio, const PKCS7 *p7) {
size_t written = 0; return BIO_write_all(bio, p7->ber_bytes, p7->ber_len);
while (written < p7->ber_len) {
size_t todo = p7->ber_len - written;
int len = todo > INT_MAX ? INT_MAX : (int)todo;
int ret = BIO_write(bio, p7->ber_bytes + written, len);
if (ret <= 0) {
return 0;
}
written += (size_t)ret;
}
return 1;
} }
void PKCS7_free(PKCS7 *p7) { void PKCS7_free(PKCS7 *p7) {

View File

@ -861,17 +861,7 @@ int i2d_PKCS12(const PKCS12 *p12, uint8_t **out) {
} }
int i2d_PKCS12_bio(BIO *bio, const PKCS12 *p12) { int i2d_PKCS12_bio(BIO *bio, const PKCS12 *p12) {
size_t written = 0; return BIO_write_all(bio, p12->ber_bytes, p12->ber_len);
while (written < p12->ber_len) {
size_t todo = p12->ber_len - written;
int len = todo > INT_MAX ? INT_MAX : (int)todo;
int ret = BIO_write(bio, p12->ber_bytes + written, len);
if (ret <= 0) {
return 0;
}
written += (size_t)ret;
}
return 1;
} }
int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12) { int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12) {

View File

@ -54,14 +54,18 @@
* copied and put under another distribution licence * copied and put under another distribution licence
* [including the GNU Public Licence.] */ * [including the GNU Public Licence.] */
#include <openssl/x509.h>
#include <limits.h>
#include <openssl/asn1.h> #include <openssl/asn1.h>
#include <openssl/buf.h> #include <openssl/buf.h>
#include <openssl/digest.h> #include <openssl/digest.h>
#include <openssl/dsa.h> #include <openssl/dsa.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/mem.h>
#include <openssl/rsa.h> #include <openssl/rsa.h>
#include <openssl/stack.h> #include <openssl/stack.h>
#include <openssl/x509.h>
int X509_verify(X509 *a, EVP_PKEY *r) int X509_verify(X509 *a, EVP_PKEY *r)
{ {
@ -201,154 +205,102 @@ int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
} }
#ifndef OPENSSL_NO_FP_API #ifndef OPENSSL_NO_FP_API
RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
{
return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPrivateKey, fp, rsa);
}
int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa) #define IMPLEMENT_D2I_FP(type, name, bio_func) \
{ type *name(FILE *fp, type **obj) { \
return ASN1_i2d_fp_of_const(RSA, i2d_RSAPrivateKey, fp, rsa); BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE); \
} if (bio == NULL) { \
return NULL; \
} \
type *ret = bio_func(bio, obj); \
BIO_free(bio); \
return ret; \
}
RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa) #define IMPLEMENT_I2D_FP(type, name, bio_func) \
{ int name(FILE *fp, type *obj) { \
return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPublicKey, fp, rsa); BIO *bio = BIO_new_fp(fp, BIO_NOCLOSE); \
} if (bio == NULL) { \
return 0; \
} \
int ret = bio_func(bio, obj); \
BIO_free(bio); \
return ret; \
}
RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa) IMPLEMENT_D2I_FP(RSA, d2i_RSAPrivateKey_fp, d2i_RSAPrivateKey_bio)
{ IMPLEMENT_I2D_FP(RSA, i2d_RSAPrivateKey_fp, i2d_RSAPrivateKey_bio)
return ASN1_d2i_fp((void *(*)(void))
RSA_new, (D2I_OF(void)) d2i_RSA_PUBKEY, fp,
(void **)rsa);
}
int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa) IMPLEMENT_D2I_FP(RSA, d2i_RSAPublicKey_fp, d2i_RSAPublicKey_bio)
{ IMPLEMENT_I2D_FP(RSA, i2d_RSAPublicKey_fp, i2d_RSAPublicKey_bio)
return ASN1_i2d_fp_of_const(RSA, i2d_RSAPublicKey, fp, rsa);
}
int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa) IMPLEMENT_D2I_FP(RSA, d2i_RSA_PUBKEY_fp, d2i_RSA_PUBKEY_bio)
{ IMPLEMENT_I2D_FP(RSA, i2d_RSA_PUBKEY_fp, i2d_RSA_PUBKEY_bio)
return ASN1_i2d_fp((I2D_OF_const(void))i2d_RSA_PUBKEY, fp, rsa);
}
#endif #endif
RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa) #define IMPLEMENT_D2I_BIO(type, name, d2i_func) \
{ type *name(BIO *bio, type **obj) { \
return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPrivateKey, bp, rsa); uint8_t *data; \
} size_t len; \
if (!BIO_read_asn1(bio, &data, &len, 100 * 1024)) { \
return NULL; \
} \
const uint8_t *ptr = data; \
type *ret = d2i_func(obj, &ptr, (long)len); \
OPENSSL_free(data); \
return ret; \
}
int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa) #define IMPLEMENT_I2D_BIO(type, name, i2d_func) \
{ int name(BIO *bio, type *obj) { \
return ASN1_i2d_bio_of_const(RSA, i2d_RSAPrivateKey, bp, rsa); uint8_t *data = NULL; \
} int len = i2d_func(obj, &data); \
if (len < 0) { \
return 0; \
} \
int ret = BIO_write_all(bio, data, len); \
OPENSSL_free(data); \
return ret; \
}
RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa) IMPLEMENT_D2I_BIO(RSA, d2i_RSAPrivateKey_bio, d2i_RSAPrivateKey)
{ IMPLEMENT_I2D_BIO(RSA, i2d_RSAPrivateKey_bio, i2d_RSAPrivateKey)
return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPublicKey, bp, rsa);
}
RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa) IMPLEMENT_D2I_BIO(RSA, d2i_RSAPublicKey_bio, d2i_RSAPublicKey)
{ IMPLEMENT_I2D_BIO(RSA, i2d_RSAPublicKey_bio, i2d_RSAPublicKey)
return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa);
}
int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa) IMPLEMENT_D2I_BIO(RSA, d2i_RSA_PUBKEY_bio, d2i_RSA_PUBKEY)
{ IMPLEMENT_I2D_BIO(RSA, i2d_RSA_PUBKEY_bio, i2d_RSA_PUBKEY)
return ASN1_i2d_bio_of_const(RSA, i2d_RSAPublicKey, bp, rsa);
}
int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
{
return ASN1_i2d_bio_of_const(RSA, i2d_RSA_PUBKEY, bp, rsa);
}
#ifndef OPENSSL_NO_DSA #ifndef OPENSSL_NO_DSA
# ifndef OPENSSL_NO_FP_API # ifndef OPENSSL_NO_FP_API
DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa) IMPLEMENT_D2I_FP(DSA, d2i_DSAPrivateKey_fp, d2i_DSAPrivateKey_bio)
{ IMPLEMENT_I2D_FP(DSA, i2d_DSAPrivateKey_fp, i2d_DSAPrivateKey_bio)
return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa);
}
int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa) IMPLEMENT_D2I_FP(DSA, d2i_DSA_PUBKEY_fp, d2i_DSA_PUBKEY_bio)
{ IMPLEMENT_I2D_FP(DSA, i2d_DSA_PUBKEY_fp, i2d_DSA_PUBKEY_bio)
return ASN1_i2d_fp_of_const(DSA, i2d_DSAPrivateKey, fp, dsa);
}
DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
{
return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa);
}
int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
{
return ASN1_i2d_fp_of_const(DSA, i2d_DSA_PUBKEY, fp, dsa);
}
# endif # endif
DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa) IMPLEMENT_D2I_BIO(DSA, d2i_DSAPrivateKey_bio, d2i_DSAPrivateKey)
{ IMPLEMENT_I2D_BIO(DSA, i2d_DSAPrivateKey_bio, i2d_DSAPrivateKey)
return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa);
}
int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa)
{
return ASN1_i2d_bio_of_const(DSA, i2d_DSAPrivateKey, bp, dsa);
}
DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
{
return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa);
}
int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
{
return ASN1_i2d_bio_of_const(DSA, i2d_DSA_PUBKEY, bp, dsa);
}
IMPLEMENT_D2I_BIO(DSA, d2i_DSA_PUBKEY_bio, d2i_DSA_PUBKEY)
IMPLEMENT_I2D_BIO(DSA, i2d_DSA_PUBKEY_bio, i2d_DSA_PUBKEY)
#endif #endif
#ifndef OPENSSL_NO_FP_API #ifndef OPENSSL_NO_FP_API
EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey) IMPLEMENT_D2I_FP(EC_KEY, d2i_ECPrivateKey_fp, d2i_ECPrivateKey_bio)
{ IMPLEMENT_I2D_FP(EC_KEY, i2d_ECPrivateKey_fp, i2d_ECPrivateKey_bio)
return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey);
}
int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey) IMPLEMENT_D2I_FP(EC_KEY, d2i_EC_PUBKEY_fp, d2i_EC_PUBKEY_bio)
{ IMPLEMENT_I2D_FP(EC_KEY, i2d_EC_PUBKEY_fp, i2d_EC_PUBKEY_bio)
return ASN1_i2d_fp_of_const(EC_KEY, i2d_EC_PUBKEY, fp, eckey);
}
EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey)
{
return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey);
}
int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey)
{
return ASN1_i2d_fp_of_const(EC_KEY, i2d_ECPrivateKey, fp, eckey);
}
#endif #endif
EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey)
{
return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey);
}
int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa) IMPLEMENT_D2I_BIO(EC_KEY, d2i_ECPrivateKey_bio, d2i_ECPrivateKey)
{ IMPLEMENT_I2D_BIO(EC_KEY, i2d_ECPrivateKey_bio, i2d_ECPrivateKey)
return ASN1_i2d_bio_of_const(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa);
}
EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey) IMPLEMENT_D2I_BIO(EC_KEY, d2i_EC_PUBKEY_bio, d2i_EC_PUBKEY)
{ IMPLEMENT_I2D_BIO(EC_KEY, i2d_EC_PUBKEY_bio, i2d_EC_PUBKEY)
return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey);
}
int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey)
{
return ASN1_i2d_bio_of_const(EC_KEY, i2d_ECPrivateKey, bp, eckey);
}
int X509_pubkey_digest(const X509 *data, const EVP_MD *type, int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
unsigned char *md, unsigned int *len) unsigned char *md, unsigned int *len)
@ -389,40 +341,18 @@ int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
} }
#ifndef OPENSSL_NO_FP_API #ifndef OPENSSL_NO_FP_API
X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8) IMPLEMENT_D2I_FP(X509_SIG, d2i_PKCS8_fp, d2i_PKCS8_bio)
{ IMPLEMENT_I2D_FP(X509_SIG, i2d_PKCS8_fp, i2d_PKCS8_bio)
return ASN1_d2i_fp_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, fp, p8);
}
int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8)
{
return ASN1_i2d_fp_of(X509_SIG, i2d_X509_SIG, fp, p8);
}
#endif #endif
X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8) IMPLEMENT_D2I_BIO(X509_SIG, d2i_PKCS8_bio, d2i_X509_SIG)
{ IMPLEMENT_I2D_BIO(X509_SIG, i2d_PKCS8_bio, i2d_X509_SIG)
return ASN1_d2i_bio_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, bp, p8);
}
int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8)
{
return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8);
}
#ifndef OPENSSL_NO_FP_API #ifndef OPENSSL_NO_FP_API
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, IMPLEMENT_D2I_FP(PKCS8_PRIV_KEY_INFO, d2i_PKCS8_PRIV_KEY_INFO_fp,
PKCS8_PRIV_KEY_INFO **p8inf) d2i_PKCS8_PRIV_KEY_INFO_bio)
{ IMPLEMENT_I2D_FP(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO_fp,
return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new, i2d_PKCS8_PRIV_KEY_INFO_bio)
d2i_PKCS8_PRIV_KEY_INFO, fp, p8inf);
}
int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf)
{
return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, fp,
p8inf);
}
int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
{ {
@ -436,38 +366,16 @@ int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
return ret; return ret;
} }
int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey) IMPLEMENT_D2I_FP(EVP_PKEY, d2i_PrivateKey_fp, d2i_PrivateKey_bio)
{ IMPLEMENT_I2D_FP(EVP_PKEY, i2d_PrivateKey_fp, i2d_PrivateKey_bio)
return ASN1_i2d_fp_of_const(EVP_PKEY, i2d_PrivateKey, fp, pkey);
}
EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a) IMPLEMENT_D2I_FP(EVP_PKEY, d2i_PUBKEY_fp, d2i_PUBKEY_bio)
{ IMPLEMENT_I2D_FP(EVP_PKEY, i2d_PUBKEY_fp, i2d_PUBKEY_bio)
return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a);
}
int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey) IMPLEMENT_D2I_BIO(PKCS8_PRIV_KEY_INFO, d2i_PKCS8_PRIV_KEY_INFO_bio,
{ d2i_PKCS8_PRIV_KEY_INFO)
return ASN1_i2d_fp_of_const(EVP_PKEY, i2d_PUBKEY, fp, pkey); IMPLEMENT_I2D_BIO(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO_bio,
} i2d_PKCS8_PRIV_KEY_INFO)
EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a)
{
return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a);
}
PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
PKCS8_PRIV_KEY_INFO **p8inf)
{
return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new,
d2i_PKCS8_PRIV_KEY_INFO, bp, p8inf);
}
int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf)
{
return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, bp,
p8inf);
}
int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
{ {
@ -482,32 +390,11 @@ int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
} }
#endif #endif
int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) IMPLEMENT_D2I_BIO(EVP_PKEY, d2i_PrivateKey_bio, d2i_AutoPrivateKey)
{ IMPLEMENT_I2D_BIO(EVP_PKEY, i2d_PrivateKey_bio, i2d_PrivateKey)
return ASN1_i2d_bio_of_const(EVP_PKEY, i2d_PrivateKey, bp, pkey);
}
EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) IMPLEMENT_D2I_BIO(EVP_PKEY, d2i_PUBKEY_bio, d2i_PUBKEY)
{ IMPLEMENT_I2D_BIO(EVP_PKEY, i2d_PUBKEY_bio, i2d_PUBKEY)
return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a);
}
int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey) IMPLEMENT_D2I_BIO(DH, d2i_DHparams_bio, d2i_DHparams)
{ IMPLEMENT_I2D_BIO(const DH, i2d_DHparams_bio, i2d_DHparams)
return ASN1_i2d_bio_of_const(EVP_PKEY, i2d_PUBKEY, bp, pkey);
}
EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a)
{
return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a);
}
DH *d2i_DHparams_bio(BIO *bp, DH **dh)
{
return ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, bp, dh);
}
int i2d_DHparams_bio(BIO *bp, const DH *dh)
{
return ASN1_i2d_bio_of_const(DH, i2d_DHparams, bp, dh);
}

View File

@ -100,12 +100,7 @@ ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES)
IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES) IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a) IMPLEMENT_ASN1_DUP_FUNCTION(GENERAL_NAME)
{
return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME,
(d2i_of_void *)d2i_GENERAL_NAME,
(char *)a);
}
/* Returns 0 if they are equal, != 0 otherwise. */ /* Returns 0 if they are equal, != 0 otherwise. */
int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)

View File

@ -302,15 +302,6 @@ typedef struct ASN1_VALUE_st ASN1_VALUE;
#define I2D_OF(type) int (*)(type *,unsigned char **) #define I2D_OF(type) int (*)(type *,unsigned char **)
#define I2D_OF_const(type) int (*)(const type *,unsigned char **) #define I2D_OF_const(type) int (*)(const type *,unsigned char **)
#define CHECKED_D2I_OF(type, d2i) \
((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0)))
#define CHECKED_I2D_OF(type, i2d) \
((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0)))
#define CHECKED_NEW_OF(type, xnew) \
((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0)))
#define CHECKED_PPTR_OF(type, p) \
((void**) (1 ? p : (type**)0))
typedef void *d2i_of_void(void **, const unsigned char **, long); typedef void *d2i_of_void(void **, const unsigned char **, long);
typedef int i2d_of_void(const void *, unsigned char **); typedef int i2d_of_void(const void *, unsigned char **);
@ -762,76 +753,17 @@ OPENSSL_EXPORT void ASN1_put_object(unsigned char **pp, int constructed, int len
OPENSSL_EXPORT int ASN1_put_eoc(unsigned char **pp); OPENSSL_EXPORT int ASN1_put_eoc(unsigned char **pp);
OPENSSL_EXPORT int ASN1_object_size(int constructed, int length, int tag); OPENSSL_EXPORT int ASN1_object_size(int constructed, int length, int tag);
/* Used to implement other functions */
OPENSSL_EXPORT void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x);
#define ASN1_dup_of(type,i2d,d2i,x) \
((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \
CHECKED_D2I_OF(type, d2i), \
CHECKED_PTR_OF(type, x)))
#define ASN1_dup_of_const(type,i2d,d2i,x) \
((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \
CHECKED_D2I_OF(type, d2i), \
CHECKED_PTR_OF(const type, x)))
OPENSSL_EXPORT void *ASN1_item_dup(const ASN1_ITEM *it, void *x); OPENSSL_EXPORT void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
/* ASN1 alloc/free macros for when a type is only used internally */
#define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type))
#define M_ASN1_free_of(x, type) \
ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type))
#ifndef OPENSSL_NO_FP_API #ifndef OPENSSL_NO_FP_API
OPENSSL_EXPORT void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x);
#define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \
CHECKED_D2I_OF(type, d2i), \
in, \
CHECKED_PPTR_OF(type, x)))
OPENSSL_EXPORT void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); OPENSSL_EXPORT void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
OPENSSL_EXPORT int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x);
#define ASN1_i2d_fp_of(type,i2d,out,x) \
(ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \
out, \
CHECKED_PTR_OF(type, x)))
#define ASN1_i2d_fp_of_const(type,i2d,out,x) \
(ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \
out, \
CHECKED_PTR_OF(const type, x)))
OPENSSL_EXPORT int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); OPENSSL_EXPORT int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
OPENSSL_EXPORT int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); OPENSSL_EXPORT int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
#endif #endif
OPENSSL_EXPORT int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in); OPENSSL_EXPORT int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
OPENSSL_EXPORT void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x);
#define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \
CHECKED_D2I_OF(type, d2i), \
in, \
CHECKED_PPTR_OF(type, x)))
OPENSSL_EXPORT void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); OPENSSL_EXPORT void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
OPENSSL_EXPORT int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, void *x);
#define ASN1_i2d_bio_of(type,i2d,out,x) \
(ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
out, \
CHECKED_PTR_OF(type, x)))
#define ASN1_i2d_bio_of_const(type,i2d,out,x) \
(ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \
out, \
CHECKED_PTR_OF(const type, x)))
OPENSSL_EXPORT int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); OPENSSL_EXPORT int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
OPENSSL_EXPORT int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); OPENSSL_EXPORT int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);

View File

@ -117,10 +117,14 @@ OPENSSL_EXPORT int BIO_read(BIO *bio, void *data, int len);
// return a line for this call, remove the warning above. // return a line for this call, remove the warning above.
OPENSSL_EXPORT int BIO_gets(BIO *bio, char *buf, int size); OPENSSL_EXPORT int BIO_gets(BIO *bio, char *buf, int size);
// BIO_write writes |len| bytes from |data| to BIO. It returns the number of // BIO_write writes |len| bytes from |data| to |bio|. It returns the number of
// bytes written or a negative number on error. // bytes written or a negative number on error.
OPENSSL_EXPORT int BIO_write(BIO *bio, const void *data, int len); OPENSSL_EXPORT int BIO_write(BIO *bio, const void *data, int len);
// BIO_write_all writes |len| bytes from |data| to |bio|, looping as necessary.
// It returns one if all bytes were successfully written and zero on error.
OPENSSL_EXPORT int BIO_write_all(BIO *bio, const void *data, size_t len);
// BIO_puts writes a NUL terminated string from |buf| to |bio|. It returns the // BIO_puts writes a NUL terminated string from |buf| to |bio|. It returns the
// number of bytes written or a negative number on error. // number of bytes written or a negative number on error.
OPENSSL_EXPORT int BIO_puts(BIO *bio, const char *buf); OPENSSL_EXPORT int BIO_puts(BIO *bio, const char *buf);

View File

@ -72,10 +72,6 @@ extern "C" {
// CHECKED_CAST casts |p| from type |from| to type |to|. // CHECKED_CAST casts |p| from type |from| to type |to|.
#define CHECKED_CAST(to, from, p) ((to) (1 ? (p) : (from)0)) #define CHECKED_CAST(to, from, p) ((to) (1 ? (p) : (from)0))
// CHECKED_PTR_OF casts a given pointer to void* and statically checks that it
// was a pointer to |type|.
#define CHECKED_PTR_OF(type, p) CHECKED_CAST(void*, type*, (p))
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define OPENSSL_COMPILE_ASSERT(cond, msg) _Static_assert(cond, #msg) #define OPENSSL_COMPILE_ASSERT(cond, msg) _Static_assert(cond, #msg)
#else #else

View File

@ -999,17 +999,25 @@ int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) {
return 1; return 1;
} }
static SSL_SESSION *ssl_session_new_with_crypto_x509(void) {
return ssl_session_new(&ssl_crypto_x509_method).release();
}
SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) { SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) {
return ASN1_d2i_bio_of(SSL_SESSION, ssl_session_new_with_crypto_x509, uint8_t *data;
d2i_SSL_SESSION, bio, out); size_t len;
if (!BIO_read_asn1(bio, &data, &len, 1024 * 1024)) {
return 0;
}
bssl::UniquePtr<uint8_t> free_data(data);
const uint8_t *ptr = data;
return d2i_SSL_SESSION(out, &ptr, static_cast<long>(len));
} }
int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) { int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) {
return ASN1_i2d_bio_of(SSL_SESSION, i2d_SSL_SESSION, bio, session); uint8_t *data;
size_t len;
if (!SSL_SESSION_to_bytes(session, &data, &len)) {
return 0;
}
bssl::UniquePtr<uint8_t> free_data(data);
return BIO_write_all(bio, data, len);
} }
IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION) IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)