make EVP_PKEY opaque
[openssl.git] / apps / x509.c
index 5938b434129807bb7d9f66ec62957ae8a4b63200..7a688a9dfe7b58f8e0ab917c5261d864484674d3 100644 (file)
@@ -55,7 +55,6 @@
  * [including the GNU Public Licence.]
  */
 
-#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -107,13 +106,9 @@ typedef enum OPTION_choice {
     OPT_PURPOSE, OPT_STARTDATE, OPT_ENDDATE, OPT_CHECKEND, OPT_CHECKHOST,
     OPT_CHECKEMAIL, OPT_CHECKIP, OPT_NOOUT, OPT_TRUSTOUT, OPT_CLRTRUST,
     OPT_CLRREJECT, OPT_ALIAS, OPT_CACREATESERIAL, OPT_CLREXT, OPT_OCSPID,
-#ifndef OPENSSL_NO_MD5
     OPT_SUBJECT_HASH_OLD,
     OPT_ISSUER_HASH_OLD,
-#endif
-#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
     OPT_FORCE_VERSION,
-#endif
     OPT_BADSIG, OPT_MD, OPT_ENGINE, OPT_NOCERT
 } OPTION_CHOICE;
 
@@ -130,12 +125,6 @@ OPTIONS x509_options[] = {
     {"serial", OPT_SERIAL, '-', "Print serial number value"},
     {"subject_hash", OPT_HASH, '-', "Print subject hash value"},
     {"issuer_hash", OPT_ISSUER_HASH, '-', "Print issuer hash value"},
-#ifndef OPENSSL_NO_MD5
-    {"subject_hash_old", OPT_SUBJECT_HASH_OLD, '-',
-     "Print old-style (MD5) issuer hash value"},
-    {"issuer_hash_old", OPT_ISSUER_HASH_OLD, '-',
-     "Print old-style (MD5) subject hash value"},
-#endif
     {"hash", OPT_HASH, '-', "Synonym for -subject_hash"},
     {"subject", OPT_SUBJECT, '-', "Print subject DN"},
     {"issuer", OPT_ISSUER, '-', "Print issuer DN"},
@@ -194,11 +183,17 @@ OPTIONS x509_options[] = {
     {"clrreject", OPT_CLRREJECT, '-'},
     {"badsig", OPT_BADSIG, '-'},
     {"", OPT_MD, '-', "Any supported digest"},
-#ifndef OPENSSL_NO_ENGINE
-    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#ifndef OPENSSL_NO_MD5
+    {"subject_hash_old", OPT_SUBJECT_HASH_OLD, '-',
+     "Print old-style (MD5) issuer hash value"},
+    {"issuer_hash_old", OPT_ISSUER_HASH_OLD, '-',
+     "Print old-style (MD5) subject hash value"},
 #endif
 #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
     {"force_version", OPT_FORCE_VERSION, 'p'},
+#endif
+#ifndef OPENSSL_NO_ENGINE
+    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
 #endif
     {NULL}
 };
@@ -232,6 +227,7 @@ int x509_main(int argc, char **argv)
     int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0;
     int checkoffset = 0, enddate = 0;
     unsigned long nmflag = 0, certflag = 0;
+    char nmflag_set = 0;
     OPTION_CHOICE o;
     ENGINE *e = NULL;
 #ifndef OPENSSL_NO_MD5
@@ -291,11 +287,11 @@ int x509_main(int argc, char **argv)
             if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg()))
                 goto opthelp;
             break;
-#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
         case OPT_FORCE_VERSION:
+#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL
             force_version = atoi(opt_arg()) - 1;
-            break;
 #endif
+            break;
         case OPT_DAYS:
             days = atoi(opt_arg());
             break;
@@ -365,6 +361,7 @@ int x509_main(int argc, char **argv)
                 goto opthelp;
             break;
         case OPT_NAMEOPT:
+            nmflag_set = 1;
             if (!set_name_ex(&nmflag, opt_arg()))
                 goto opthelp;
             break;
@@ -459,6 +456,10 @@ int x509_main(int argc, char **argv)
         case OPT_ISSUER_HASH_OLD:
             issuer_hash_old = ++num;
             break;
+#else
+        case OPT_SUBJECT_HASH_OLD:
+        case OPT_ISSUER_HASH_OLD:
+            break;
 #endif
         case OPT_DATES:
             startdate = ++num;
@@ -489,7 +490,10 @@ int x509_main(int argc, char **argv)
         goto opthelp;
     }
 
-    out = bio_open_default(outfile, "w");
+    if (!nmflag_set)
+        nmflag = XN_FLAG_ONELINE;
+
+    out = bio_open_default(outfile, 'w', outformat);
     if (out == NULL)
         goto end;
 
@@ -521,19 +525,9 @@ int x509_main(int argc, char **argv)
     }
 
     if (extfile) {
-        long errorline = -1;
         X509V3_CTX ctx2;
-        extconf = NCONF_new(NULL);
-        if (!NCONF_load(extconf, extfile, &errorline)) {
-            if (errorline <= 0)
-                BIO_printf(bio_err,
-                           "error loading the config file '%s'\n", extfile);
-            else
-                BIO_printf(bio_err,
-                           "error on line %ld of config file '%s'\n",
-                           errorline, extfile);
+        if ((extconf = app_load_config(extfile)) == NULL)
             goto end;
-        }
         if (!extsect) {
             extsect = NCONF_get_string(extconf, "default", "extensions");
             if (!extsect) {
@@ -559,7 +553,7 @@ int x509_main(int argc, char **argv)
             BIO_printf(bio_err, "We need a private key to sign with\n");
             goto end;
         }
-        in = bio_open_default(infile, "r");
+        in = bio_open_default(infile, 'r', informat);
         if (in == NULL)
             goto end;
         req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
@@ -570,15 +564,6 @@ int x509_main(int argc, char **argv)
             goto end;
         }
 
-        if ((req->req_info == NULL) ||
-            (req->req_info->pubkey == NULL) ||
-            (req->req_info->pubkey->public_key == NULL) ||
-            (req->req_info->pubkey->public_key->data == NULL)) {
-            BIO_printf(bio_err,
-                       "The certificate request appears to corrupted\n");
-            BIO_printf(bio_err, "It does not contain a public key\n");
-            goto end;
-        }
         if ((pkey = X509_REQ_get_pubkey(req)) == NULL) {
             BIO_printf(bio_err, "error unpacking public key\n");
             goto end;
@@ -605,7 +590,7 @@ int x509_main(int argc, char **argv)
 
         if (sno == NULL) {
             sno = ASN1_INTEGER_new();
-            if (!sno || !rand_serial(NULL, sno))
+            if (sno == NULL || !rand_serial(NULL, sno))
                 goto end;
             if (!X509_set_serialNumber(x, sno))
                 goto end;
@@ -614,9 +599,9 @@ int x509_main(int argc, char **argv)
         } else if (!X509_set_serialNumber(x, sno))
             goto end;
 
-        if (!X509_set_issuer_name(x, req->req_info->subject))
+        if (!X509_set_issuer_name(x, X509_REQ_get_subject_name(req)))
             goto end;
-        if (!X509_set_subject_name(x, req->req_info->subject))
+        if (!X509_set_subject_name(x, X509_REQ_get_subject_name(req)))
             goto end;
 
         X509_gmtime_adj(X509_get_notBefore(x), 0);
@@ -738,7 +723,7 @@ int x509_main(int argc, char **argv)
             } else if (modulus == i) {
                 EVP_PKEY *pkey;
 
-                pkey = X509_get_pubkey(x);
+                pkey = X509_get0_pubkey(x);
                 if (pkey == NULL) {
                     BIO_printf(bio_err, "Modulus=unavailable\n");
                     ERR_print_errors(bio_err);
@@ -746,29 +731,27 @@ int x509_main(int argc, char **argv)
                 }
                 BIO_printf(out, "Modulus=");
 #ifndef OPENSSL_NO_RSA
-                if (pkey->type == EVP_PKEY_RSA)
-                    BN_print(out, pkey->pkey.rsa->n);
+                if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA)
+                    BN_print(out, EVP_PKEY_get0_RSA(pkey)->n);
                 else
 #endif
 #ifndef OPENSSL_NO_DSA
-                if (pkey->type == EVP_PKEY_DSA)
-                    BN_print(out, pkey->pkey.dsa->pub_key);
+                if (EVP_PKEY_id(pkey) == EVP_PKEY_DSA)
+                    BN_print(out, EVP_PKEY_get0_DSA(pkey)->pub_key);
                 else
 #endif
                     BIO_printf(out, "Wrong Algorithm type");
                 BIO_printf(out, "\n");
-                EVP_PKEY_free(pkey);
             } else if (pubkey == i) {
                 EVP_PKEY *pkey;
 
-                pkey = X509_get_pubkey(x);
+                pkey = X509_get0_pubkey(x);
                 if (pkey == NULL) {
                     BIO_printf(bio_err, "Error getting public key\n");
                     ERR_print_errors(bio_err);
                     goto end;
                 }
                 PEM_write_bio_PUBKEY(out, pkey);
-                EVP_PKEY_free(pkey);
             } else if (C == i) {
                 unsigned char *d;
                 char *m;
@@ -906,8 +889,13 @@ int x509_main(int argc, char **argv)
         goto end;
     }
 
-    if (badsig)
-        x->signature->data[x->signature->length - 1] ^= 0x1;
+    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 (outformat == FORMAT_ASN1)
         i = i2d_X509_bio(out, x);
@@ -916,16 +904,6 @@ int x509_main(int argc, char **argv)
             i = PEM_write_bio_X509_AUX(out, x);
         else
             i = PEM_write_bio_X509(out, x);
-    } else if (outformat == FORMAT_NETSCAPE) {
-        NETSCAPE_X509 nx;
-        ASN1_OCTET_STRING hdr;
-
-        hdr.data = (unsigned char *)NETSCAPE_CERT_HDR;
-        hdr.length = strlen(NETSCAPE_CERT_HDR);
-        nx.header = &hdr;
-        nx.cert = x;
-
-        i = ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509), out, &nx);
     } else {
         BIO_printf(bio_err, "bad output format specified for outfile\n");
         goto end;
@@ -971,15 +949,15 @@ static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile,
            : (strlen(serialfile))) + 1;
     buf = app_malloc(len, "serial# buffer");
     if (serialfile == NULL) {
-        BUF_strlcpy(buf, CAfile, len);
+        OPENSSL_strlcpy(buf, CAfile, len);
         for (p = buf; *p; p++)
             if (*p == '.') {
                 *p = '\0';
                 break;
             }
-        BUF_strlcat(buf, POSTFIX, len);
+        OPENSSL_strlcat(buf, POSTFIX, len);
     } else
-        BUF_strlcpy(buf, serialfile, len);
+        OPENSSL_strlcpy(buf, serialfile, len);
 
     serial = load_serial(buf, create, NULL);
     if (serial == NULL)
@@ -1011,9 +989,8 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
     X509_STORE_CTX xsc;
     EVP_PKEY *upkey;
 
-    upkey = X509_get_pubkey(xca);
+    upkey = X509_get0_pubkey(xca);
     EVP_PKEY_copy_parameters(upkey, pkey);
-    EVP_PKEY_free(upkey);
 
     if (!X509_STORE_CTX_init(&xsc, ctx, x, NULL)) {
         BIO_printf(bio_err, "Error initialising X509 store\n");
@@ -1021,11 +998,9 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
     }
     if (sno)
         bs = sno;
-    else if (!(bs = x509_load_serial(CAfile, serialfile, create)))
+    else if ((bs = x509_load_serial(CAfile, serialfile, create)) == NULL)
         goto end;
 
-/*      if (!X509_STORE_add_cert(ctx,x)) goto end;*/
-
     /*
      * NOTE: this certificate can/should be self signed, unless it was a
      * certificate request in which case it is not.
@@ -1126,8 +1101,7 @@ static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
     if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
         goto err;
 
-    if (X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * days) ==
-        NULL)
+    if (X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL) == NULL)
         goto err;
 
     if (!X509_set_pubkey(x, pkey))