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>
diff --git a/crypto/asn1/a_d2i_fp.c b/crypto/asn1/a_d2i_fp.c
index ee71ee9..fd423e2 100644
--- a/crypto/asn1/a_d2i_fp.c
+++ b/crypto/asn1/a_d2i_fp.c
@@ -58,66 +58,24 @@
#include <limits.h>
-#include <openssl/buf.h>
+#include <openssl/bio.h>
#include <openssl/err.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)
{
- 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 = (const unsigned char *)b->data;
- ret = ASN1_item_d2i(x, &p, len, it);
- err:
- if (b != NULL)
- BUF_MEM_free(b);
- return (ret);
+ uint8_t *data;
+ size_t len;
+ // Historically, this function did not impose a limit in OpenSSL and is used
+ // to read CRLs, so we leave this without an external bound.
+ if (!BIO_read_asn1(in, &data, &len, INT_MAX)) {
+ return NULL;
+ }
+ const uint8_t *ptr = data;
+ void *ret = ASN1_item_d2i(x, &ptr, len, it);
+ OPENSSL_free(data);
+ return ret;
}
#ifndef OPENSSL_NO_FP_API
@@ -133,158 +91,3 @@
return ret;
}
#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;
-}
diff --git a/crypto/asn1/a_dup.c b/crypto/asn1/a_dup.c
index 57394f5..9ede851 100644
--- a/crypto/asn1/a_dup.c
+++ b/crypto/asn1/a_dup.c
@@ -59,30 +59,6 @@
#include <openssl/err.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
* need to allocate the buffer. At some point this could be rewritten to
diff --git a/crypto/asn1/a_i2d_fp.c b/crypto/asn1/a_i2d_fp.c
index 5cc97d2..db0d812 100644
--- a/crypto/asn1/a_i2d_fp.c
+++ b/crypto/asn1/a_i2d_fp.c
@@ -56,54 +56,10 @@
#include <openssl/asn1.h>
+#include <openssl/bio.h>
#include <openssl/err.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)
{
@@ -120,25 +76,13 @@
int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
{
unsigned char *b = NULL;
- int i, j = 0, n, ret = 1;
-
- n = ASN1_item_i2d(x, &b, it);
+ int n = ASN1_item_i2d(x, &b, it);
if (b == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return (0);
+ return 0;
}
- for (;;) {
- i = BIO_write(out, &(b[j]), n);
- if (i == n)
- break;
- if (i <= 0) {
- ret = 0;
- break;
- }
- j += i;
- n -= i;
- }
+ int ret = BIO_write_all(out, b, n);
OPENSSL_free(b);
- return (ret);
+ return ret;
}
diff --git a/crypto/bio/bio.c b/crypto/bio/bio.c
index 3e788b8..881c14e 100644
--- a/crypto/bio/bio.c
+++ b/crypto/bio/bio.c
@@ -177,6 +177,19 @@
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) {
return BIO_write(bio, in, strlen(in));
}
diff --git a/crypto/pkcs7/pkcs7_x509.c b/crypto/pkcs7/pkcs7_x509.c
index a2a6b46..d6ca44e 100644
--- a/crypto/pkcs7/pkcs7_x509.c
+++ b/crypto/pkcs7/pkcs7_x509.c
@@ -333,17 +333,7 @@
}
int i2d_PKCS7_bio(BIO *bio, const PKCS7 *p7) {
- size_t written = 0;
- 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;
+ return BIO_write_all(bio, p7->ber_bytes, p7->ber_len);
}
void PKCS7_free(PKCS7 *p7) {
diff --git a/crypto/pkcs8/pkcs8_x509.c b/crypto/pkcs8/pkcs8_x509.c
index dc74d96..2c7841e 100644
--- a/crypto/pkcs8/pkcs8_x509.c
+++ b/crypto/pkcs8/pkcs8_x509.c
@@ -861,17 +861,7 @@
}
int i2d_PKCS12_bio(BIO *bio, const PKCS12 *p12) {
- size_t written = 0;
- 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;
+ return BIO_write_all(bio, p12->ber_bytes, p12->ber_len);
}
int i2d_PKCS12_fp(FILE *fp, const PKCS12 *p12) {
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index 064c89c..a37d7bd 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -54,14 +54,18 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
+#include <openssl/x509.h>
+
+#include <limits.h>
+
#include <openssl/asn1.h>
#include <openssl/buf.h>
#include <openssl/digest.h>
#include <openssl/dsa.h>
#include <openssl/evp.h>
+#include <openssl/mem.h>
#include <openssl/rsa.h>
#include <openssl/stack.h>
-#include <openssl/x509.h>
int X509_verify(X509 *a, EVP_PKEY *r)
{
@@ -201,154 +205,102 @@
}
#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)
-{
- return ASN1_i2d_fp_of_const(RSA, i2d_RSAPrivateKey, fp, rsa);
-}
+#define IMPLEMENT_D2I_FP(type, name, bio_func) \
+ type *name(FILE *fp, type **obj) { \
+ 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)
-{
- return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPublicKey, fp, rsa);
-}
+#define IMPLEMENT_I2D_FP(type, name, bio_func) \
+ int name(FILE *fp, type *obj) { \
+ 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)
-{
- return ASN1_d2i_fp((void *(*)(void))
- RSA_new, (D2I_OF(void)) d2i_RSA_PUBKEY, fp,
- (void **)rsa);
-}
+IMPLEMENT_D2I_FP(RSA, d2i_RSAPrivateKey_fp, d2i_RSAPrivateKey_bio)
+IMPLEMENT_I2D_FP(RSA, i2d_RSAPrivateKey_fp, i2d_RSAPrivateKey_bio)
-int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
-{
- return ASN1_i2d_fp_of_const(RSA, i2d_RSAPublicKey, fp, rsa);
-}
+IMPLEMENT_D2I_FP(RSA, d2i_RSAPublicKey_fp, d2i_RSAPublicKey_bio)
+IMPLEMENT_I2D_FP(RSA, i2d_RSAPublicKey_fp, i2d_RSAPublicKey_bio)
-int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
-{
- return ASN1_i2d_fp((I2D_OF_const(void))i2d_RSA_PUBKEY, fp, 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)
#endif
-RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
-{
- return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPrivateKey, bp, rsa);
-}
+#define IMPLEMENT_D2I_BIO(type, name, d2i_func) \
+ type *name(BIO *bio, type **obj) { \
+ 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)
-{
- return ASN1_i2d_bio_of_const(RSA, i2d_RSAPrivateKey, bp, rsa);
-}
+#define IMPLEMENT_I2D_BIO(type, name, i2d_func) \
+ int name(BIO *bio, type *obj) { \
+ 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)
-{
- return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPublicKey, bp, rsa);
-}
+IMPLEMENT_D2I_BIO(RSA, d2i_RSAPrivateKey_bio, d2i_RSAPrivateKey)
+IMPLEMENT_I2D_BIO(RSA, i2d_RSAPrivateKey_bio, i2d_RSAPrivateKey)
-RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
-{
- return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa);
-}
+IMPLEMENT_D2I_BIO(RSA, d2i_RSAPublicKey_bio, d2i_RSAPublicKey)
+IMPLEMENT_I2D_BIO(RSA, i2d_RSAPublicKey_bio, i2d_RSAPublicKey)
-int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
-{
- 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);
-}
+IMPLEMENT_D2I_BIO(RSA, d2i_RSA_PUBKEY_bio, d2i_RSA_PUBKEY)
+IMPLEMENT_I2D_BIO(RSA, i2d_RSA_PUBKEY_bio, i2d_RSA_PUBKEY)
#ifndef OPENSSL_NO_DSA
# ifndef OPENSSL_NO_FP_API
-DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa)
-{
- return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa);
-}
+IMPLEMENT_D2I_FP(DSA, d2i_DSAPrivateKey_fp, d2i_DSAPrivateKey_bio)
+IMPLEMENT_I2D_FP(DSA, i2d_DSAPrivateKey_fp, i2d_DSAPrivateKey_bio)
-int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa)
-{
- 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);
-}
+IMPLEMENT_D2I_FP(DSA, d2i_DSA_PUBKEY_fp, d2i_DSA_PUBKEY_bio)
+IMPLEMENT_I2D_FP(DSA, i2d_DSA_PUBKEY_fp, i2d_DSA_PUBKEY_bio)
# endif
-DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa)
-{
- return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa);
-}
+IMPLEMENT_D2I_BIO(DSA, d2i_DSAPrivateKey_bio, d2i_DSAPrivateKey)
+IMPLEMENT_I2D_BIO(DSA, i2d_DSAPrivateKey_bio, i2d_DSAPrivateKey)
-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
#ifndef OPENSSL_NO_FP_API
-EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey)
-{
- return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey);
-}
+IMPLEMENT_D2I_FP(EC_KEY, d2i_ECPrivateKey_fp, d2i_ECPrivateKey_bio)
+IMPLEMENT_I2D_FP(EC_KEY, i2d_ECPrivateKey_fp, i2d_ECPrivateKey_bio)
-int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey)
-{
- 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);
-}
+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)
#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)
-{
- return ASN1_i2d_bio_of_const(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa);
-}
+IMPLEMENT_D2I_BIO(EC_KEY, d2i_ECPrivateKey_bio, d2i_ECPrivateKey)
+IMPLEMENT_I2D_BIO(EC_KEY, i2d_ECPrivateKey_bio, i2d_ECPrivateKey)
-EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey)
-{
- 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);
-}
+IMPLEMENT_D2I_BIO(EC_KEY, d2i_EC_PUBKEY_bio, d2i_EC_PUBKEY)
+IMPLEMENT_I2D_BIO(EC_KEY, i2d_EC_PUBKEY_bio, i2d_EC_PUBKEY)
int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
unsigned char *md, unsigned int *len)
@@ -389,40 +341,18 @@
}
#ifndef OPENSSL_NO_FP_API
-X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8)
-{
- 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);
-}
+IMPLEMENT_D2I_FP(X509_SIG, d2i_PKCS8_fp, d2i_PKCS8_bio)
+IMPLEMENT_I2D_FP(X509_SIG, i2d_PKCS8_fp, i2d_PKCS8_bio)
#endif
-X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8)
-{
- 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);
-}
+IMPLEMENT_D2I_BIO(X509_SIG, d2i_PKCS8_bio, d2i_X509_SIG)
+IMPLEMENT_I2D_BIO(X509_SIG, i2d_PKCS8_bio, i2d_X509_SIG)
#ifndef OPENSSL_NO_FP_API
-PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
- PKCS8_PRIV_KEY_INFO **p8inf)
-{
- return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new,
- 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);
-}
+IMPLEMENT_D2I_FP(PKCS8_PRIV_KEY_INFO, d2i_PKCS8_PRIV_KEY_INFO_fp,
+ d2i_PKCS8_PRIV_KEY_INFO_bio)
+IMPLEMENT_I2D_FP(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO_fp,
+ i2d_PKCS8_PRIV_KEY_INFO_bio)
int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key)
{
@@ -436,38 +366,16 @@
return ret;
}
-int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey)
-{
- return ASN1_i2d_fp_of_const(EVP_PKEY, i2d_PrivateKey, fp, pkey);
-}
+IMPLEMENT_D2I_FP(EVP_PKEY, d2i_PrivateKey_fp, d2i_PrivateKey_bio)
+IMPLEMENT_I2D_FP(EVP_PKEY, i2d_PrivateKey_fp, i2d_PrivateKey_bio)
-EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a)
-{
- return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a);
-}
+IMPLEMENT_D2I_FP(EVP_PKEY, d2i_PUBKEY_fp, d2i_PUBKEY_bio)
+IMPLEMENT_I2D_FP(EVP_PKEY, i2d_PUBKEY_fp, i2d_PUBKEY_bio)
-int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
-{
- return ASN1_i2d_fp_of_const(EVP_PKEY, i2d_PUBKEY, fp, pkey);
-}
-
-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);
-}
+IMPLEMENT_D2I_BIO(PKCS8_PRIV_KEY_INFO, d2i_PKCS8_PRIV_KEY_INFO_bio,
+ d2i_PKCS8_PRIV_KEY_INFO)
+IMPLEMENT_I2D_BIO(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO_bio,
+ i2d_PKCS8_PRIV_KEY_INFO)
int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key)
{
@@ -482,32 +390,11 @@
}
#endif
-int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey)
-{
- return ASN1_i2d_bio_of_const(EVP_PKEY, i2d_PrivateKey, bp, pkey);
-}
+IMPLEMENT_D2I_BIO(EVP_PKEY, d2i_PrivateKey_bio, d2i_AutoPrivateKey)
+IMPLEMENT_I2D_BIO(EVP_PKEY, i2d_PrivateKey_bio, i2d_PrivateKey)
-EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a)
-{
- return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a);
-}
+IMPLEMENT_D2I_BIO(EVP_PKEY, d2i_PUBKEY_bio, d2i_PUBKEY)
+IMPLEMENT_I2D_BIO(EVP_PKEY, i2d_PUBKEY_bio, i2d_PUBKEY)
-int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
-{
- 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);
-}
+IMPLEMENT_D2I_BIO(DH, d2i_DHparams_bio, d2i_DHparams)
+IMPLEMENT_I2D_BIO(const DH, i2d_DHparams_bio, i2d_DHparams)
diff --git a/crypto/x509v3/v3_genn.c b/crypto/x509v3/v3_genn.c
index 8c92687..552a524 100644
--- a/crypto/x509v3/v3_genn.c
+++ b/crypto/x509v3/v3_genn.c
@@ -100,12 +100,7 @@
IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES)
-GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a)
-{
- return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME,
- (d2i_of_void *)d2i_GENERAL_NAME,
- (char *)a);
-}
+IMPLEMENT_ASN1_DUP_FUNCTION(GENERAL_NAME)
/* Returns 0 if they are equal, != 0 otherwise. */
int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h
index 46e5f53..7be3d63 100644
--- a/include/openssl/asn1.h
+++ b/include/openssl/asn1.h
@@ -302,15 +302,6 @@
#define I2D_OF(type) int (*)(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 int i2d_of_void(const void *, unsigned char **);
@@ -762,76 +753,17 @@
OPENSSL_EXPORT int ASN1_put_eoc(unsigned char **pp);
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);
-/* 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
-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 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_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
#endif
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 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_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a);
OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a);
diff --git a/include/openssl/bio.h b/include/openssl/bio.h
index 70c2fbf..8e2db65 100644
--- a/include/openssl/bio.h
+++ b/include/openssl/bio.h
@@ -117,10 +117,14 @@
// return a line for this call, remove the warning above.
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.
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
// number of bytes written or a negative number on error.
OPENSSL_EXPORT int BIO_puts(BIO *bio, const char *buf);
diff --git a/include/openssl/type_check.h b/include/openssl/type_check.h
index da78d70..e5d7047 100644
--- a/include/openssl/type_check.h
+++ b/include/openssl/type_check.h
@@ -72,10 +72,6 @@
// CHECKED_CAST casts |p| from type |from| to type |to|.
#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
#define OPENSSL_COMPILE_ASSERT(cond, msg) _Static_assert(cond, #msg)
#else
diff --git a/ssl/ssl_x509.cc b/ssl/ssl_x509.cc
index 9fa800f..ec203b2 100644
--- a/ssl/ssl_x509.cc
+++ b/ssl/ssl_x509.cc
@@ -999,17 +999,25 @@
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) {
- return ASN1_d2i_bio_of(SSL_SESSION, ssl_session_new_with_crypto_x509,
- d2i_SSL_SESSION, bio, out);
+ uint8_t *data;
+ 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) {
- 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)