Add ASN1_STRING_get0_data(), deprecate ASN1_STRING_data().

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>
diff --git a/apps/apps.c b/apps/apps.c
index 746f565..17a9fdc 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -1938,7 +1938,7 @@
         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 @@
     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;
+}
diff --git a/apps/apps.h b/apps/apps.h
index 33a2f68..8fb6f44 100644
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -71,6 +71,8 @@
 int has_stdin_waiting(void);
 # endif
 
+int corrupt_signature(ASN1_STRING *signature);
+
 /*
  * Common verification options.
  */
diff --git a/apps/ca.c b/apps/ca.c
index 331c136..4b4b37d 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -988,7 +988,7 @@
             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");
diff --git a/apps/cms.c b/apps/cms.c
index 5899760..b5ae970 100644
--- a/apps/cms.c
+++ b/apps/cms.c
@@ -1177,13 +1177,13 @@
             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) {
diff --git a/apps/crl.c b/apps/crl.c
index 3e30bdc..6ea0b4c 100644
--- a/apps/crl.c
+++ b/apps/crl.c
@@ -321,10 +321,9 @@
 
     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)
diff --git a/apps/ocsp.c b/apps/ocsp.c
index 1cb11b2..1766878 100644
--- a/apps/ocsp.c
+++ b/apps/ocsp.c
@@ -951,8 +951,8 @@
 
     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);
diff --git a/apps/x509.c b/apps/x509.c
index ed49c4e..93b0eae 100644
--- a/apps/x509.c
+++ b/apps/x509.c
@@ -849,10 +849,9 @@
 
     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)