New option to 'x509' -next_serial. This outputs the certificate
[openssl.git] / apps / x509.c
index 9a6f9817906250627784a10d0defb9bbda497ca6..6e652177d88f557f3aa6a782b7c84a726157a60f 100644 (file)
@@ -73,6 +73,8 @@
 #include <openssl/x509v3.h>
 #include <openssl/objects.h>
 #include <openssl/pem.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
 
 #undef PROG
 #define PROG x509_main
@@ -92,7 +94,9 @@ static char *x509_usage[]={
 " -out arg        - output file - default stdout\n",
 " -passin arg     - private key password source\n",
 " -serial         - print serial number value\n",
-" -hash           - print hash value\n",
+" -subject_hash   - print subject hash value\n",
+" -issuer_hash    - print issuer hash value\n",
+" -hash           - synonym for -subject_hash\n",
 " -subject        - print subject DN\n",
 " -issuer         - print issuer DN\n",
 " -email          - print email address(es)\n",
@@ -167,8 +171,9 @@ int MAIN(int argc, char **argv)
        char *infile=NULL,*outfile=NULL,*keyfile=NULL,*CAfile=NULL;
        char *CAkeyfile=NULL,*CAserial=NULL;
        char *alias=NULL;
-       int text=0,serial=0,hash=0,subject=0,issuer=0,startdate=0,enddate=0;
-       int ocspid=0;
+       int text=0,serial=0,subject=0,issuer=0,startdate=0,enddate=0;
+       int next_serial=0;
+       int subject_hash=0,issuer_hash=0,ocspid=0;
        int noout=0,sign_flag=0,CA_flag=0,CA_createserial=0,email=0;
        int trustout=0,clrtrust=0,clrreject=0,aliasout=0,clrext=0;
        int C=0;
@@ -371,6 +376,8 @@ int MAIN(int argc, char **argv)
                        email= ++num;
                else if (strcmp(*argv,"-serial") == 0)
                        serial= ++num;
+               else if (strcmp(*argv,"-next_serial") == 0)
+                       next_serial= ++num;
                else if (strcmp(*argv,"-modulus") == 0)
                        modulus= ++num;
                else if (strcmp(*argv,"-pubkey") == 0)
@@ -379,8 +386,11 @@ int MAIN(int argc, char **argv)
                        x509req= ++num;
                else if (strcmp(*argv,"-text") == 0)
                        text= ++num;
-               else if (strcmp(*argv,"-hash") == 0)
-                       hash= ++num;
+               else if (strcmp(*argv,"-hash") == 0
+                       || strcmp(*argv,"-subject_hash") == 0)
+                       subject_hash= ++num;
+               else if (strcmp(*argv,"-issuer_hash") == 0)
+                       issuer_hash= ++num;
                else if (strcmp(*argv,"-subject") == 0)
                        subject= ++num;
                else if (strcmp(*argv,"-issuer") == 0)
@@ -617,7 +627,7 @@ bad:
                if (xca == NULL) goto end;
                }
 
-       if (!noout || text)
+       if (!noout || text || next_serial)
                {
                OBJ_create("2.99999.3",
                        "SET.ex3","SET x509v3 extension 3");
@@ -688,9 +698,28 @@ bad:
                        else if (serial == i)
                                {
                                BIO_printf(STDout,"serial=");
-                               i2a_ASN1_INTEGER(STDout,x->cert_info->serialNumber);
+                               i2a_ASN1_INTEGER(STDout,
+                                       X509_get_serialNumber(x));
                                BIO_printf(STDout,"\n");
                                }
+                       else if (next_serial == i)
+                               {
+                               BIGNUM *bnser;
+                               ASN1_INTEGER *ser;
+                               ser = X509_get_serialNumber(x);
+                               bnser = ASN1_INTEGER_to_BN(ser, NULL);
+                               if (!bnser)
+                                       goto end;
+                               if (!BN_add_word(bnser, 1))
+                                       goto end;
+                               ser = BN_to_ASN1_INTEGER(bnser, NULL);
+                               if (!ser)
+                                       goto end;
+                               BN_free(bnser);
+                               i2a_ASN1_INTEGER(out, ser);
+                               ASN1_INTEGER_free(ser);
+                               BIO_puts(out, "\n");
+                               }
                        else if (email == i) 
                                {
                                int j;
@@ -707,10 +736,14 @@ bad:
                                if (alstr) BIO_printf(STDout,"%s\n", alstr);
                                else BIO_puts(STDout,"<No Alias>\n");
                                }
-                       else if (hash == i)
+                       else if (subject_hash == i)
                                {
                                BIO_printf(STDout,"%08lx\n",X509_subject_name_hash(x));
                                }
+                       else if (issuer_hash == i)
+                               {
+                               BIO_printf(STDout,"%08lx\n",X509_issuer_name_hash(x));
+                               }
                        else if (pprint == i)
                                {
                                X509_PURPOSE *ptmp;
@@ -1034,105 +1067,44 @@ end:
        OPENSSL_EXIT(ret);
        }
 
-static ASN1_INTEGER *load_serial(char *CAfile, char *serialfile, int create)
+static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile, int create)
        {
        char *buf = NULL, *p;
-       MS_STATIC char buf2[1024];
-       ASN1_INTEGER *bs = NULL, *bs2 = NULL;
-       BIO *io = NULL;
+       ASN1_INTEGER *bs = NULL;
        BIGNUM *serial = NULL;
+       size_t len;
 
-       buf=OPENSSL_malloc( ((serialfile == NULL)
-                       ?(strlen(CAfile)+strlen(POSTFIX)+1)
-                       :(strlen(serialfile)))+1);
+       len = ((serialfile == NULL)
+               ?(strlen(CAfile)+strlen(POSTFIX)+1)
+               :(strlen(serialfile)))+1;
+       buf=OPENSSL_malloc(len);
        if (buf == NULL) { BIO_printf(bio_err,"out of mem\n"); goto end; }
        if (serialfile == NULL)
                {
-               strcpy(buf,CAfile);
+               BUF_strlcpy(buf,CAfile,len);
                for (p=buf; *p; p++)
                        if (*p == '.')
                                {
                                *p='\0';
                                break;
                                }
-               strcat(buf,POSTFIX);
+               BUF_strlcat(buf,POSTFIX,len);
                }
        else
-               strcpy(buf,serialfile);
-       serial=BN_new();
-       bs=ASN1_INTEGER_new();
-       if ((serial == NULL) || (bs == NULL))
-               {
-               ERR_print_errors(bio_err);
-               goto end;
-               }
+               BUF_strlcpy(buf,serialfile,len);
 
-       io=BIO_new(BIO_s_file());
-       if (io == NULL)
-               {
-               ERR_print_errors(bio_err);
-               goto end;
-               }
-       
-       if (BIO_read_filename(io,buf) <= 0)
-               {
-               if (!create)
-                       {
-                       perror(buf);
-                       goto end;
-                       }
-               else
-                       {
-                       ASN1_INTEGER_set(bs,1);
-                       BN_one(serial);
-                       }
-               }
-       else 
-               {
-               if (!a2i_ASN1_INTEGER(io,bs,buf2,sizeof buf2))
-                       {
-                       BIO_printf(bio_err,"unable to load serial number from %s\n",buf);
-                       ERR_print_errors(bio_err);
-                       goto end;
-                       }
-               else
-                       {
-                       serial=BN_bin2bn(bs->data,bs->length,serial);
-                       if (serial == NULL)
-                               {
-                               BIO_printf(bio_err,"error converting bin 2 bn");
-                               goto end;
-                               }
-                       }
-               }
+       serial = load_serial(buf, create, NULL);
+       if (serial == NULL) goto end;
 
        if (!BN_add_word(serial,1))
                { BIO_printf(bio_err,"add_word failure\n"); goto end; }
-       if (!(bs2 = BN_to_ASN1_INTEGER(serial, NULL)))
-               { BIO_printf(bio_err,"error converting bn 2 asn1_integer\n"); goto end; }
-       if (BIO_write_filename(io,buf) <= 0)
-               {
-               BIO_printf(bio_err,"error attempting to write serial number file\n");
-               perror(buf);
-               goto end;
-               }
-       i2a_ASN1_INTEGER(io,bs2);
-       BIO_puts(io,"\n");
 
-       BIO_free(io);
-       if (buf) OPENSSL_free(buf);
-       ASN1_INTEGER_free(bs2);
-       BN_free(serial);
-       io=NULL;
-       return bs;
+       if (!save_serial(buf, NULL, serial, &bs)) goto end;
 
      end:
+ end:
        if (buf) OPENSSL_free(buf);
-       BIO_free(io);
-       ASN1_INTEGER_free(bs);
        BN_free(serial);
-       return NULL;
-
+       return bs;
        }
 
 static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
@@ -1154,10 +1126,10 @@ static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
                goto end;
                }
        if (sno) bs = sno;
-       else if (!(bs = load_serial(CAfile, serialfile, create)))
+       else if (!(bs = x509_load_serial(CAfile, serialfile, create)))
                goto end;
 
-       if (!X509_STORE_add_cert(ctx,x)) 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. */