More X509 V3 stuff. Add support for extensions in the 'req' application
[openssl.git] / apps / req.c
index f51345f5a2890f731a83757762d759121b023057..523139ecda528c456e3ead0b629249be5ebef9b2 100644 (file)
@@ -71,6 +71,7 @@
 #include "err.h"
 #include "asn1.h"
 #include "x509.h"
+#include "x509v3.h"
 #include "objects.h"
 #include "pem.h"
 
@@ -80,6 +81,7 @@
 #define KEYFILE                "default_keyfile"
 #define DISTINGUISHED_NAME     "distinguished_name"
 #define ATTRIBUTES     "attributes"
+#define V3_EXTENSIONS  "x509_extensions"
 
 #define DEFAULT_KEY_LENGTH     512
 #define MIN_KEY_LENGTH         384
@@ -147,6 +149,7 @@ char **argv;
        int informat,outformat,verify=0,noout=0,text=0,keyform=FORMAT_PEM;
        int nodes=0,kludge=0;
        char *infile,*outfile,*prog,*keyfile=NULL,*template=NULL,*keyout=NULL;
+       char *extensions = NULL;
        EVP_CIPHER *cipher=NULL;
        int modulus=0;
        char *p;
@@ -221,13 +224,16 @@ char **argv;
                        }
                else if (strcmp(*argv,"-newkey") == 0)
                        {
+                       int is_numeric;
+
                        if (--argc < 1) goto bad;
                        p= *(++argv);
-                       if ((strncmp("rsa:",p,4) == 0) ||
-                               ((p[0] >= '0') && (p[0] <= '9')))
+                       is_numeric = p[0] >= '0' && p[0] <= '9';
+                       if (strncmp("rsa:",p,4) == 0 || is_numeric)
                                {
                                pkey_type=TYPE_RSA;
-                               p+=4;
+                               if(!is_numeric)
+                                   p+=4;
                                newkey= atoi(p);
                                }
                        else
@@ -354,15 +360,18 @@ bad:
                }
 
        ERR_load_crypto_strings();
+       X509V3_add_standard_extensions();
 
 #ifndef MONOLITH
        /* Lets load up our environment a little */
-       p=getenv("SSLEAY_CONF");
+       p=getenv("OPENSSL_CONF");
+       if (p == NULL)
+               p=getenv("SSLEAY_CONF");
        if (p == NULL)
                {
                strcpy(config_name,X509_get_default_cert_area());
                strcat(config_name,"/lib/");
-               strcat(config_name,SSLEAY_CONF);
+               strcat(config_name,OPENSSL_CONF);
                p=config_name;
                }
         default_config_file=p;
@@ -392,6 +401,29 @@ bad:
                        }
                }
 
+       if (req_conf != NULL)
+               {
+               p=CONF_get_string(req_conf,NULL,"oid_file");
+               if (p != NULL)
+                       {
+                       BIO *oid_bio;
+
+                       oid_bio=BIO_new_file(p,"r");
+                       if (oid_bio == NULL) 
+                               {
+                               /*
+                               BIO_printf(bio_err,"problems opening %s for extra oid's\n",p);
+                               ERR_print_errors(bio_err);
+                               */
+                               }
+                       else
+                               {
+                               OBJ_create_objects(oid_bio);
+                               BIO_free(oid_bio);
+                               }
+                       }
+               }
+
        if ((md_alg == NULL) &&
                ((p=CONF_get_string(req_conf,SECTION,"default_md")) != NULL))
                {
@@ -399,6 +431,8 @@ bad:
                        digest=md_alg;
                }
 
+       extensions = CONF_get_string(req_conf, SECTION, V3_EXTENSIONS);
+
        in=BIO_new(BIO_s_file());
        out=BIO_new(BIO_s_file());
        if ((in == NULL) || (out == NULL))
@@ -599,12 +633,12 @@ loop:
                        }
                if (x509)
                        {
+                       EVP_PKEY *tmppkey;
+                       X509V3_CTX ext_ctx;
                        if ((x509ss=X509_new()) == NULL) goto end;
 
-                       /* don't set the version number, for starters
-                        * the field is null and second, null is v0 
-                        * if (!ASN1_INTEGER_set(ci->version,0L)) goto end;
-                        */
+                       /* Set version to V3 */
+                       if(!X509_set_version(x509ss, 2)) goto end;
                        ASN1_INTEGER_set(X509_get_serialNumber(x509ss),0L);
 
                        X509_set_issuer_name(x509ss,
@@ -614,7 +648,19 @@ loop:
                                (long)60*60*24*days);
                        X509_set_subject_name(x509ss,
                                X509_REQ_get_subject_name(req));
-                       X509_set_pubkey(x509ss,X509_REQ_get_pubkey(req));
+                       tmppkey = X509_REQ_get_pubkey(req);
+                       X509_set_pubkey(x509ss,tmppkey);
+                       EVP_PKEY_free(tmppkey);
+
+                       /* Set up V3 context struct */
+
+                       ext_ctx.issuer_cert = x509ss;
+                       ext_ctx.subject_cert = x509ss;
+                       ext_ctx.subject_req = NULL;
+
+                       /* Add extensions */
+                       if(extensions && !X509V3_EXT_add_conf(req_conf, 
+                                       &ext_ctx, extensions, x509ss)) goto end;
 
                        if (!(i=X509_sign(x509ss,pkey,digest)))
                                goto end;
@@ -638,7 +684,10 @@ loop:
                        }
 
                i=X509_REQ_verify(req,pkey);
-               if (tmp) pkey=NULL;
+               if (tmp) {
+                       EVP_PKEY_free(pkey);
+                       pkey=NULL;
+               }
 
                if (i < 0)
                        {
@@ -695,9 +744,11 @@ loop:
                        goto end; 
                        }
                fprintf(stdout,"Modulus=");
+#ifndef NO_RSA
                if (pubkey->type == EVP_PKEY_RSA)
                        BN_print(out,pubkey->pkey.rsa->n);
                else
+#endif
                        fprintf(stdout,"Wrong Algorithm type");
                fprintf(stdout,"\n");
                }