Security framework.
[openssl.git] / apps / req.c
index 7953f9ddc177439cfd727fd247fbc90229602f4f..316163ff786af3790d774574c771350519948a27 100644 (file)
@@ -165,7 +165,7 @@ int MAIN(int argc, char **argv)
        EVP_PKEY_CTX *genctx = NULL;
        const char *keyalg = NULL;
        char *keyalgstr = NULL;
-       STACK *pkeyopts = NULL;
+       STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL;
        EVP_PKEY *pkey=NULL;
        int i=0,badops=0,newreq=0,verbose=0,pkey_type=-1;
        long newkey = -1;
@@ -306,8 +306,17 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1)
                                goto bad;
                        if (!pkeyopts)
-                               pkeyopts = sk_new_null();
-                       if (!pkeyopts || !sk_push(pkeyopts, *(++argv)))
+                               pkeyopts = sk_OPENSSL_STRING_new_null();
+                       if (!pkeyopts || !sk_OPENSSL_STRING_push(pkeyopts, *(++argv)))
+                               goto bad;
+                       }
+               else if (strcmp(*argv,"-sigopt") == 0)
+                       {
+                       if (--argc < 1)
+                               goto bad;
+                       if (!sigopts)
+                               sigopts = sk_OPENSSL_STRING_new_null();
+                       if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
                                goto bad;
                        }
                else if (strcmp(*argv,"-batch") == 0)
@@ -365,11 +374,6 @@ int MAIN(int argc, char **argv)
                        serial = s2i_ASN1_INTEGER(NULL, *(++argv));
                        if (!serial) goto bad;
                        }
-               else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
-                       {
-                       /* ok */
-                       digest=md_alg;
-                       }
                else if (strcmp(*argv,"-extensions") == 0)
                        {
                        if (--argc < 1) goto bad;
@@ -380,6 +384,11 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1) goto bad;
                        req_exts = *(++argv);
                        }
+               else if ((md_alg=EVP_get_digestbyname(&((*argv)[1]))) != NULL)
+                       {
+                       /* ok */
+                       digest=md_alg;
+                       }
                else
                        {
                        BIO_printf(bio_err,"unknown option %s\n",*argv);
@@ -635,6 +644,11 @@ bad:
                if (inrand)
                        app_RAND_load_files(inrand);
 
+               if (!NCONF_get_number(req_conf,SECTION,BITS, &newkey))
+                       {
+                       newkey=DEFAULT_KEY_LENGTH;
+                       }
+
                if (keyalg)
                        {
                        genctx = set_keygen_ctx(bio_err, keyalg, &pkey_type, &newkey,
@@ -643,12 +657,6 @@ bad:
                                goto end;
                        }
        
-               if (newkey <= 0)
-                       {
-                       if (!NCONF_get_number(req_conf,SECTION,BITS, &newkey))
-                               newkey=DEFAULT_KEY_LENGTH;
-                       }
-
                if (newkey < MIN_KEY_LENGTH && (pkey_type == EVP_PKEY_RSA || pkey_type == EVP_PKEY_DSA))
                        {
                        BIO_printf(bio_err,"private key length is too short,\n");
@@ -667,9 +675,9 @@ bad:
                if (pkeyopts)
                        {
                        char *genopt;
-                       for (i = 0; i < sk_num(pkeyopts); i++)
+                       for (i = 0; i < sk_OPENSSL_STRING_num(pkeyopts); i++)
                                {
-                               genopt = sk_value(pkeyopts, i);
+                               genopt = sk_OPENSSL_STRING_value(pkeyopts, i);
                                if (pkey_ctrl_string(genctx, genopt) <= 0)
                                        {
                                        BIO_printf(bio_err,
@@ -838,7 +846,7 @@ loop:
 
                        if (!X509_set_issuer_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
                        if (!X509_gmtime_adj(X509_get_notBefore(x509ss),0)) goto end;
-                       if (!X509_gmtime_adj(X509_get_notAfter(x509ss), (long)60*60*24*days)) goto end;
+                       if (!X509_time_adj_ex(X509_get_notAfter(x509ss), days, 0, NULL)) goto end;
                        if (!X509_set_subject_name(x509ss, X509_REQ_get_subject_name(req))) goto end;
                        tmppkey = X509_REQ_get_pubkey(req);
                        if (!tmppkey || !X509_set_pubkey(x509ss,tmppkey)) goto end;
@@ -858,8 +866,9 @@ loop:
                                        extensions);
                                goto end;
                                }
-                       
-                       if (!(i=X509_sign(x509ss,pkey,digest)))
+
+                       i=do_X509_sign(bio_err, x509ss, pkey, digest, sigopts);
+                       if (!i)
                                {
                                ERR_print_errors(bio_err);
                                goto end;
@@ -883,7 +892,8 @@ loop:
                                        req_exts);
                                goto end;
                                }
-                       if (!(i=X509_REQ_sign(req,pkey,digest)))
+                       i=do_X509_REQ_sign(bio_err, req, pkey, digest, sigopts);
+                       if (!i)
                                {
                                ERR_print_errors(bio_err);
                                goto end;
@@ -893,7 +903,7 @@ loop:
 
        if (subj && x509)
                {
-               BIO_printf(bio_err, "Cannot modifiy certificate subject\n");
+               BIO_printf(bio_err, "Cannot modify certificate subject\n");
                goto end;
                }
 
@@ -1083,7 +1093,9 @@ end:
        if (genctx)
                EVP_PKEY_CTX_free(genctx);
        if (pkeyopts)
-               sk_free(pkeyopts);
+               sk_OPENSSL_STRING_free(pkeyopts);
+       if (sigopts)
+               sk_OPENSSL_STRING_free(sigopts);
 #ifndef OPENSSL_NO_ENGINE
        if (gen_eng)
                ENGINE_free(gen_eng);
@@ -1146,15 +1158,12 @@ static int make_REQ(X509_REQ *req, EVP_PKEY *pkey, char *subj, int multirdn,
        /* setup version number */
        if (!X509_REQ_set_version(req,0L)) goto err; /* version 1 */
 
-       if (no_prompt) 
+       if (subj)
+               i = build_subject(req, subj, chtype, multirdn);
+       else if (no_prompt) 
                i = auto_info(req, dn_sk, attr_sk, attribs, chtype);
-       else 
-               {
-               if (subj)
-                       i = build_subject(req, subj, chtype, multirdn);
-               else
-                       i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype);
-               }
+       else
+               i = prompt_info(req, dn_sk, dn_sect, attr_sk, attr_sect, attribs, chtype);
        if(!i) goto err;
 
        if (!X509_REQ_set_pubkey(req,pkey)) goto err;
@@ -1336,11 +1345,17 @@ start2:                 for (;;)
 
                                BIO_snprintf(buf,sizeof buf,"%s_min",type);
                                if (!NCONF_get_number(req_conf,attr_sect,buf, &n_min))
+                                       {
+                                       ERR_clear_error();
                                        n_min = -1;
+                                       }
 
                                BIO_snprintf(buf,sizeof buf,"%s_max",type);
                                if (!NCONF_get_number(req_conf,attr_sect,buf, &n_max))
+                                       {
+                                       ERR_clear_error();
                                        n_max = -1;
+                                       }
 
                                if (!add_attribute_object(req,
                                        v->value,def,value,nid,n_min,n_max, chtype))
@@ -1441,7 +1456,8 @@ start:
                buf[0]='\0';
                if (!batch)
                        {
-                       fgets(buf,sizeof buf,stdin);
+                       if (!fgets(buf,sizeof buf,stdin))
+                               return 0;
                        }
                else
                        {
@@ -1499,7 +1515,8 @@ start:
                buf[0]='\0';
                if (!batch)
                        {
-                       fgets(buf,sizeof buf,stdin);
+                       if (!fgets(buf,sizeof buf,stdin))
+                               return 0;
                        }
                else
                        {
@@ -1628,6 +1645,8 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type,
                                keylen = atol(p + 1);
                                *pkeylen = keylen;
                                }
+                       else
+                               keylen = *pkeylen;
                        }
                else if (p)
                        paramfile = p + 1;
@@ -1715,7 +1734,7 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type,
                ERR_print_errors(err);
                return NULL;
                }
-
+#ifndef OPENSSL_NO_RSA
        if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1))
                {
                if (EVP_PKEY_CTX_set_rsa_keygen_bits(gctx, keylen) <= 0)
@@ -1726,6 +1745,7 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr, int *pkey_type,
                        return NULL;
                        }
                }
+#endif
 
        return gctx;
        }
@@ -1747,3 +1767,68 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx)
 #endif
        return 1;
        }
+
+static int do_sign_init(BIO *err, EVP_MD_CTX *ctx, EVP_PKEY *pkey,
+                       const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts)
+       {
+       EVP_PKEY_CTX *pkctx = NULL;
+       int i;
+       EVP_MD_CTX_init(ctx);
+       if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey))
+               return 0;
+       for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++)
+               {
+               char *sigopt = sk_OPENSSL_STRING_value(sigopts, i);
+               if (pkey_ctrl_string(pkctx, sigopt) <= 0)
+                       {
+                       BIO_printf(err, "parameter error \"%s\"\n", sigopt);
+                       ERR_print_errors(bio_err);
+                       return 0;
+                       }
+               }
+       return 1;
+       }
+
+int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
+                       STACK_OF(OPENSSL_STRING) *sigopts)
+       {
+       int rv;
+       EVP_MD_CTX mctx;
+       EVP_MD_CTX_init(&mctx);
+       rv = do_sign_init(err, &mctx, pkey, md, sigopts);
+       if (rv > 0)
+               rv = X509_sign_ctx(x, &mctx);
+       EVP_MD_CTX_cleanup(&mctx);
+       return rv > 0 ? 1 : 0;
+       }
+
+
+int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
+                       STACK_OF(OPENSSL_STRING) *sigopts)
+       {
+       int rv;
+       EVP_MD_CTX mctx;
+       EVP_MD_CTX_init(&mctx);
+       rv = do_sign_init(err, &mctx, pkey, md, sigopts);
+       if (rv > 0)
+               rv = X509_REQ_sign_ctx(x, &mctx);
+       EVP_MD_CTX_cleanup(&mctx);
+       return rv > 0 ? 1 : 0;
+       }
+               
+       
+
+int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
+                       STACK_OF(OPENSSL_STRING) *sigopts)
+       {
+       int rv;
+       EVP_MD_CTX mctx;
+       EVP_MD_CTX_init(&mctx);
+       rv = do_sign_init(err, &mctx, pkey, md, sigopts);
+       if (rv > 0)
+               rv = X509_CRL_sign_ctx(x, &mctx);
+       EVP_MD_CTX_cleanup(&mctx);
+       return rv > 0 ? 1 : 0;
+       }
+               
+