Add ASN1_STRING_get0_data(), deprecate ASN1_STRING_data().
authorDr. Stephen Henson <steve@openssl.org>
Tue, 16 Aug 2016 13:06:48 +0000 (14:06 +0100)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 16 Aug 2016 15:05:35 +0000 (16:05 +0100)
Deprecate the function ASN1_STRING_data() and replace with a new function
ASN1_STRING_get0_data() which returns a constant pointer. Update library
to use new function.

Reviewed-by: Rich Salz <rsalz@openssl.org>
25 files changed:
apps/apps.c
apps/apps.h
apps/ca.c
apps/cms.c
apps/crl.c
apps/ocsp.c
apps/x509.c
crypto/asn1/asn1_lib.c
crypto/asn1/evp_asn1.c
crypto/asn1/p5_pbe.c
crypto/asn1/p8_pkey.c
crypto/ct/ct_prn.c
crypto/dh/dh_ameth.c
crypto/ec/ec_ameth.c
crypto/ec/ec_asn1.c
crypto/ec/ecx_meth.c
crypto/pkcs12/p12_mutl.c
crypto/ts/ts_lib.c
crypto/ts/ts_rsp_verify.c
crypto/ts/ts_verify_ctx.c
crypto/x509/t_x509.c
crypto/x509v3/v3_lib.c
crypto/x509v3/v3_prn.c
doc/crypto/ASN1_STRING_length.pod
include/openssl/asn1.h

index 746f565a90dc3280c267fda10289513eb7fa6773..17a9fdc2671f4fe28cf631d2bea8f2c20325f99f 100644 (file)
@@ -1938,7 +1938,7 @@ static const char *get_dp_url(DIST_POINT *dp)
         gen = sk_GENERAL_NAME_value(gens, i);
         uri = GENERAL_NAME_get0_value(gen, &gtype);
         if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6) {
-            char *uptr = (char *)ASN1_STRING_data(uri);
+            const char *uptr = (const char *)ASN1_STRING_get0_data(uri);
             if (strncmp(uptr, "http://", 7) == 0)
                 return uptr;
         }
@@ -2581,3 +2581,17 @@ int has_stdin_waiting(void)
     return _kbhit();
 }
 #endif
+
+/* Corrupt a signature by modifying final byte */
+int corrupt_signature(ASN1_STRING *signature)
+{
+        unsigned char *s;
+        size_t slen = ASN1_STRING_length(signature);
+
+        s = OPENSSL_memdup(ASN1_STRING_get0_data(signature), slen);
+        if (s == NULL)
+            return 0;
+        s[slen - 1] ^= 0x1;
+        ASN1_STRING_set0(signature, s, slen);
+        return 1;
+}
index 33a2f683fa549df0a5a96bc7a388585d10bb8c2b..8fb6f44f2f7debc7832daa8937d1336d100dd805 100644 (file)
@@ -71,6 +71,8 @@ void wait_for_async(SSL *s);
 int has_stdin_waiting(void);
 # endif
 
+int corrupt_signature(ASN1_STRING *signature);
+
 /*
  * Common verification options.
  */
index 331c1364dcc64984a6672c1338f0b4f7c7137619..4b4b37d59eb15815093d4f0bf19ac93a5e94c444 100644 (file)
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -988,7 +988,7 @@ end_of_options:
             x = sk_X509_value(cert_sk, i);
 
             j = ASN1_STRING_length(serialNumber);
-            p = (const char *)ASN1_STRING_data(serialNumber);
+            p = (const char *)ASN1_STRING_get0_data(serialNumber);
 
             if (strlen(outdir) >= (size_t)(j ? BSIZE - j * 2 - 6 : BSIZE - 8)) {
                 BIO_printf(bio_err, "certificate file name too long\n");
index 5899760a90f95286c11ffbb5c92bfa33539fd2d8..b5ae97090f6cdc5eb73af015eb2a1b94fc8a9990 100644 (file)
@@ -1177,13 +1177,13 @@ static void receipt_request_print(CMS_ContentInfo *cms)
             BIO_puts(bio_err, "  Receipt Request Parse Error\n");
             ERR_print_errors(bio_err);
         } else {
-            char *id;
+            const char *id;
             int idlen;
             CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
                                            &rlist, &rto);
             BIO_puts(bio_err, "  Signed Content ID:\n");
             idlen = ASN1_STRING_length(scid);
-            id = (char *)ASN1_STRING_data(scid);
+            id = (const char *)ASN1_STRING_get0_data(scid);
             BIO_dump_indent(bio_err, id, idlen, 4);
             BIO_puts(bio_err, "  Receipts From");
             if (rlist) {
index 3e30bdc59c12b91c4784251d99b49b97b7cf0092..6ea0b4c32bf31392e7f32c53383ea94cdb9a3695 100644 (file)
@@ -321,10 +321,9 @@ int crl_main(int argc, char **argv)
 
     if (badsig) {
         ASN1_BIT_STRING *sig;
-        unsigned char *psig;
         X509_CRL_get0_signature(&sig, NULL, x);
-        psig = ASN1_STRING_data(sig);
-        psig[ASN1_STRING_length(sig) - 1] ^= 0x1;
+        if (!corrupt_signature(sig))
+            goto end;
     }
 
     if (outformat == FORMAT_ASN1)
index 1cb11b289bb52ba4464f8690a6fde0b8936c85f6..17668788df0c04d4226352db9a37c08f2c53fd9a 100644 (file)
@@ -951,8 +951,8 @@ static void make_ocsp_response(OCSP_RESPONSE **resp, OCSP_REQUEST *req,
 
     if (badsig) {
         ASN1_OCTET_STRING *sig = OCSP_resp_get0_signature(bs);
-        unsigned char *sigptr = ASN1_STRING_data(sig);
-        sigptr[ASN1_STRING_length(sig) - 1] ^= 0x1;
+        if (!corrupt_signature(sig))
+            goto end;
     }
 
     *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_SUCCESSFUL, bs);
index ed49c4e8fbc90da401b532816e49f6efe7b1ba85..93b0eae85250a3458a130f82c3c135da3e2b52cc 100644 (file)
@@ -849,10 +849,9 @@ int x509_main(int argc, char **argv)
 
     if (badsig) {
         ASN1_BIT_STRING *signature;
-        unsigned char *s;
         X509_get0_signature(&signature, NULL, x);
-        s = ASN1_STRING_data(signature);
-        s[ASN1_STRING_length(signature) - 1] ^= 0x1;
+        if (!corrupt_signature(signature))
+            goto end;
     }
 
     if (outformat == FORMAT_ASN1)
index 1b521077a9e5c885860129eb52984ddbb0ff69d7..f2f07ac2d5171a1762f3b92f8fce9a84d96f2af5 100644 (file)
@@ -363,7 +363,14 @@ int ASN1_STRING_type(const ASN1_STRING *x)
     return x->type;
 }
 
+const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x)
+{
+    return x->data;
+}
+
+# if OPENSSL_API_COMPAT < 0x10100000L
 unsigned char *ASN1_STRING_data(ASN1_STRING *x)
 {
     return x->data;
 }
+#endif
index ad3a5bc7a0a3747a6fcf19a94f3ae359a4fb6d88..a458367ebdd1030cba39376c49207c2dba143123 100644 (file)
@@ -30,13 +30,13 @@ int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
 int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len)
 {
     int ret, num;
-    unsigned char *p;
+    const unsigned char *p;
 
     if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) {
         ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
         return (-1);
     }
-    p = ASN1_STRING_data(a->value.octet_string);
+    p = ASN1_STRING_get0_data(a->value.octet_string);
     ret = ASN1_STRING_length(a->value.octet_string);
     if (ret < max_len)
         num = ret;
@@ -105,7 +105,7 @@ int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num,
         n = max_len;
 
     if (data != NULL)
-        memcpy(data, ASN1_STRING_data(atmp->oct), n);
+        memcpy(data, ASN1_STRING_get0_data(atmp->oct), n);
     if (ret == -1) {
  err:
         ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
index 92da23ec3bceb212c6cdab5c3b2199f07b25c220..ab7e16898fa388fd00495a8741aa0748f91ddfa4 100644 (file)
@@ -29,7 +29,7 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
 {
     PBEPARAM *pbe = NULL;
     ASN1_STRING *pbe_str = NULL;
-    unsigned char *sstr;
+    unsigned char *sstr = NULL;
 
     pbe = PBEPARAM_new();
     if (pbe == NULL) {
@@ -44,16 +44,20 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
     }
     if (!saltlen)
         saltlen = PKCS5_SALT_LEN;
-    if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) {
+
+    sstr = OPENSSL_malloc(saltlen);
+    if (sstr == NULL) {
         ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
         goto err;
     }
-    sstr = ASN1_STRING_data(pbe->salt);
     if (salt)
         memcpy(sstr, salt, saltlen);
     else if (RAND_bytes(sstr, saltlen) <= 0)
         goto err;
 
+    ASN1_STRING_set0(pbe->salt, sstr, saltlen);
+    sstr = NULL;
+
     if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) {
         ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
         goto err;
@@ -66,6 +70,7 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
         return 1;
 
  err:
+    OPENSSL_free(sstr);
     PBEPARAM_free(pbe);
     ASN1_STRING_free(pbe_str);
     return 0;
index ebee6b50cd9493537623435ed003741e3ad5de26..c08aa8526796c644b8f5b85b014089dbc415335a 100644 (file)
@@ -57,7 +57,7 @@ int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
     if (ppkalg)
         *ppkalg = p8->pkeyalg->algorithm;
     if (pk) {
-        *pk = ASN1_STRING_data(p8->pkey);
+        *pk = ASN1_STRING_get0_data(p8->pkey);
         *ppklen = ASN1_STRING_length(p8->pkey);
     }
     if (pa)
index 2786746997b364b5741493ba4e0ba4b9337c5d9b..376e04523e5726b4fc42d2945a8785dbbfc48c1c 100644 (file)
@@ -41,7 +41,7 @@ static void timestamp_print(uint64_t timestamp, BIO *out)
      * characters long with a final Z. Update it with fractional seconds.
      */
     BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ",
-                 ASN1_STRING_data(gen), (unsigned int)(timestamp % 1000));
+                 ASN1_STRING_get0_data(gen), (unsigned int)(timestamp % 1000));
     if (ASN1_GENERALIZEDTIME_set_string(gen, genstr))
         ASN1_GENERALIZEDTIME_print(out, gen);
     ASN1_GENERALIZEDTIME_free(gen);
index 78aea36093263ee2d58d18393f4d402d5cb737df..2e67eeb66a47f783e17c07dc9216022d48ad0f86 100644 (file)
@@ -600,7 +600,7 @@ static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
     dhpeer = DHparams_dup(pk->pkey.dh);
     /* We have parameters now set public key */
     plen = ASN1_STRING_length(pubkey);
-    p = ASN1_STRING_data(pubkey);
+    p = ASN1_STRING_get0_data(pubkey);
     if (!p || !plen)
         goto err;
 
@@ -690,7 +690,7 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
 
     if (ukm) {
         dukmlen = ASN1_STRING_length(ukm);
-        dukm = OPENSSL_memdup(ASN1_STRING_data(ukm), dukmlen);
+        dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen);
         if (!dukm)
             goto err;
     }
@@ -834,7 +834,7 @@ static int dh_cms_encrypt(CMS_RecipientInfo *ri)
 
     if (ukm) {
         dukmlen = ASN1_STRING_length(ukm);
-        dukm = OPENSSL_memdup(ASN1_STRING_data(ukm), dukmlen);
+        dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen);
         if (!dukm)
             goto err;
     }
index f6a3f5c15fab7c735c0d0353c01bcb2bee8c70cf..44dfbb4ae6eafffcc2f4de865fec35a0be6df543 100644 (file)
@@ -593,7 +593,7 @@ static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
     }
     /* We have parameters now set public key */
     plen = ASN1_STRING_length(pubkey);
-    p = ASN1_STRING_data(pubkey);
+    p = ASN1_STRING_get0_data(pubkey);
     if (!p || !plen)
         goto err;
     if (!o2i_ECPublicKey(&ecpeer, &p, plen))
index 8714a4b1d801aa8eaa4ff10bce8cd74ec56bfcf4..e10deff165f8cddd679b99b0641bf9a70d4fc236 100644 (file)
@@ -948,7 +948,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
 
     if (priv_key->privateKey) {
         ASN1_OCTET_STRING *pkey = priv_key->privateKey;
-        if (EC_KEY_oct2priv(ret, ASN1_STRING_data(pkey),
+        if (EC_KEY_oct2priv(ret, ASN1_STRING_get0_data(pkey),
                             ASN1_STRING_length(pkey)) == 0)
             goto err;
     } else {
@@ -967,7 +967,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len)
         const unsigned char *pub_oct;
         int pub_oct_len;
 
-        pub_oct = ASN1_STRING_data(priv_key->publicKey);
+        pub_oct = ASN1_STRING_get0_data(priv_key->publicKey);
         pub_oct_len = ASN1_STRING_length(priv_key->publicKey);
         if (!EC_KEY_oct2key(ret, pub_oct, pub_oct_len, NULL)) {
             ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB);
index 354d3879467fa8a0ce96e4257f335fe8658ad7f6..f7179511ddd3ce4f7dee0c931bc039219d597c67 100644 (file)
@@ -151,7 +151,7 @@ static int ecx_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
         p = NULL;
         plen = 0;
     } else {
-        p = ASN1_STRING_data(oct);
+        p = ASN1_STRING_get0_data(oct);
         plen = ASN1_STRING_length(oct);
     }
 
index 9bd672a17c4cca70f645635ab71cf0caf899512b..9c0c4df458a98ea8e4a9446319399ca90dede360 100644 (file)
@@ -143,7 +143,7 @@ int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
     }
     X509_SIG_get0(NULL, &macoct, p12->mac->dinfo);
     if ((maclen != (unsigned int)ASN1_STRING_length(macoct))
-        || CRYPTO_memcmp(mac, ASN1_STRING_data(macoct), maclen))
+        || CRYPTO_memcmp(mac, ASN1_STRING_get0_data(macoct), maclen))
         return 0;
     return 1;
 }
index e18f1f3f7e3ff93b9d83dedfd5b5c3d35da3ff98..99c0580f2aef39da1c496f9b6cec67d79ba2f891 100644 (file)
@@ -85,7 +85,7 @@ int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a)
 
     BIO_printf(bio, "Message data:\n");
     msg = a->hashed_msg;
-    BIO_dump_indent(bio, (const char *)ASN1_STRING_data(msg),
+    BIO_dump_indent(bio, (const char *)ASN1_STRING_get0_data(msg),
                     ASN1_STRING_length(msg), 4);
 
     return 1;
index 99f664b431e5335a2567ba5a9abe3fcf09eb8a11..2755dd0ef36b5ce389e45de0d5f36cec6fc62d6f 100644 (file)
@@ -472,7 +472,7 @@ static char *ts_get_status_text(STACK_OF(ASN1_UTF8STRING) *text)
         length = ASN1_STRING_length(current);
         if (i > 0)
             *p++ = '/';
-        strncpy(p, (const char *)ASN1_STRING_data(current), length);
+        strncpy(p, (const char *)ASN1_STRING_get0_data(current), length);
         p += length;
     }
     *p = '\0';
@@ -568,7 +568,7 @@ static int ts_check_imprints(X509_ALGOR *algor_a,
     }
 
     ret = len_a == (unsigned)ASN1_STRING_length(b->hashed_msg) &&
-        memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0;
+        memcmp(imprint_a, ASN1_STRING_get0_data(b->hashed_msg), len_a) == 0;
  err:
     if (!ret)
         TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH);
index 141385d79f6beb82584f8245780c596086a51b05..d4792ee04f597d00dcf8c07b58585c6f0c52aa9d 100644 (file)
@@ -128,7 +128,7 @@ TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx)
     ret->imprint_len = ASN1_STRING_length(msg);
     if ((ret->imprint = OPENSSL_malloc(ret->imprint_len)) == NULL)
         goto err;
-    memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len);
+    memcpy(ret->imprint, ASN1_STRING_get0_data(msg), ret->imprint_len);
 
     if ((nonce = req->nonce) != NULL) {
         if ((ret->nonce = ASN1_INTEGER_dup(nonce)) == NULL)
index 5fbe76768ee236fdca7df3273c9db3bb7d9e4b3f..c96ada82a9eebb64df5b612da2eba0617d36db09 100644 (file)
@@ -248,8 +248,9 @@ int X509_ocspid_print(BIO *bp, X509 *x)
     if (keybstr == NULL)
         goto err;
 
-    if (!EVP_Digest(ASN1_STRING_data(keybstr), ASN1_STRING_length(keybstr),
-                    SHA1md, NULL, EVP_sha1(), NULL))
+    if (!EVP_Digest(ASN1_STRING_get0_data(keybstr),
+                    ASN1_STRING_length(keybstr), SHA1md, NULL, EVP_sha1(),
+                    NULL))
         goto err;
     for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
         if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
index 25d019e6847739265ecda970ed2f48d8baee1aac..a3ca720fe1343c3e97a020795019db4e39955573 100644 (file)
@@ -203,7 +203,7 @@ void *X509V3_EXT_d2i(X509_EXTENSION *ext)
     if ((method = X509V3_EXT_get(ext)) == NULL)
         return NULL;
     extvalue = X509_EXTENSION_get_data(ext);
-    p = ASN1_STRING_data(extvalue);
+    p = ASN1_STRING_get0_data(extvalue);
     extlen = ASN1_STRING_length(extvalue);
     if (method->it)
         return ASN1_item_d2i(NULL, &p, extlen, ASN1_ITEM_ptr(method->it));
index 3048b67588e57e00656df88e54cb5b5455277f90..4b1d0c3b5ee88eb283a776926446615686102413 100644 (file)
@@ -79,7 +79,7 @@ int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag,
     int ok = 1;
 
     extoct = X509_EXTENSION_get_data(ext);
-    p = ASN1_STRING_data(extoct);
+    p = ASN1_STRING_get0_data(extoct);
     extlen = ASN1_STRING_length(extoct);
 
     if ((method = X509V3_EXT_get(ext)) == NULL)
index a57de1c093345cb686e83c1a462a051ec609eee0..26cb176142c64f0478a574edd8c125703d9f54ee 100644 (file)
@@ -3,14 +3,15 @@
 =head1 NAME
 
 ASN1_STRING_dup, ASN1_STRING_cmp, ASN1_STRING_set, ASN1_STRING_length,
-ASN1_STRING_type, ASN1_STRING_data, ASN1_STRING_to_UTF8 -
-ASN1_STRING utility functions
+ASN1_STRING_type, ASN1_STRING_get0_data, ASN1_STRING_data,
+ASN1_STRING_to_UTF8 - ASN1_STRING utility functions
 
 =head1 SYNOPSIS
 
  #include <openssl/asn1.h>
 
  int ASN1_STRING_length(ASN1_STRING *x);
+ const unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x);
  unsigned char * ASN1_STRING_data(ASN1_STRING *x);
 
  ASN1_STRING * ASN1_STRING_dup(ASN1_STRING *a);
@@ -29,10 +30,14 @@ These functions allow an B<ASN1_STRING> structure to be manipulated.
 
 ASN1_STRING_length() returns the length of the content of B<x>.
 
-ASN1_STRING_data() returns an internal pointer to the data of B<x>.
+ASN1_STRING_get0_data() returns an internal pointer to the data of B<x>.
 Since this is an internal pointer it should B<not> be freed or
 modified in any way.
 
+ASN1_STRING_data() is similar to ASN1_STRING_get0_data() except the
+returned value is not constant. This function is deprecated:
+applications should use ASN1_STRING_get0_data() instead.
+
 ASN1_STRING_dup() returns a copy of the structure B<a>.
 
 ASN1_STRING_cmp() compares B<a> and B<b> returning 0 if the two
index fcf6de99670438ef82cb940f5b63bc1cbfd510bf..40526fbaa23617a9ab0e072de17af96026529114 100644 (file)
@@ -550,7 +550,8 @@ void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
 int ASN1_STRING_length(const ASN1_STRING *x);
 void ASN1_STRING_length_set(ASN1_STRING *x, int n);
 int ASN1_STRING_type(const ASN1_STRING *x);
-unsigned char *ASN1_STRING_data(ASN1_STRING *x);
+DEPRECATEDIN_1_1_0(unsigned char *ASN1_STRING_data(ASN1_STRING *x))
+const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
 int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length);