~ubuntu-branches/ubuntu/hardy/openssl/hardy-security

« back to all changes in this revision

Viewing changes to apps/ca.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2005-12-13 21:37:42 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051213213742-7em5nrw5c7ceegyd
Tags: 0.9.8a-5
Stop ssh from crashing randomly on sparc (Closes: #335912)
Patch from upstream cvs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
83
83
#    else
84
84
#      include <unixlib.h>
85
85
#    endif
86
 
#  elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS)
 
86
#  elif !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_NETWARE)
87
87
#    include <sys/file.h>
88
88
#  endif
89
89
#endif
105
105
 
106
106
#define ENV_DEFAULT_CA          "default_ca"
107
107
 
 
108
#define STRING_MASK     "string_mask"
 
109
#define UTF8_IN                 "utf8"
 
110
 
108
111
#define ENV_DIR                 "dir"
109
112
#define ENV_CERTS               "certs"
110
113
#define ENV_CRL_DIR             "crl_dir"
131
134
#define ENV_NAMEOPT             "name_opt"
132
135
#define ENV_CERTOPT             "cert_opt"
133
136
#define ENV_EXTCOPY             "copy_extensions"
 
137
#define ENV_UNIQUE_SUBJECT      "unique_subject"
134
138
 
135
139
#define ENV_DATABASE            "database"
136
140
 
142
146
#define REV_KEY_COMPROMISE      3       /* Value is cert key compromise time */
143
147
#define REV_CA_COMPROMISE       4       /* Value is CA key compromise time */
144
148
 
145
 
static char *ca_usage[]={
 
149
static const char *ca_usage[]={
146
150
"usage: ca args\n",
147
151
"\n",
148
152
" -verbose        - Talk alot while doing things\n",
160
164
" -keyform arg    - private key file format (PEM or ENGINE)\n",
161
165
" -key arg        - key to decode the private key if it is encrypted\n",
162
166
" -cert file      - The CA certificate\n",
 
167
" -selfsign       - sign a certificate with the key associated with it\n",
163
168
" -in file        - The input PEM encoded certificate request(s)\n",
164
169
" -out file       - Where to put the output file(s)\n",
165
170
" -outdir dir     - Where to put output certificates\n",
172
177
" -msie_hack      - msie modifications to handle all those universal strings\n",
173
178
" -revoke file    - Revoke a certificate (given in file)\n",
174
179
" -subj arg       - Use arg instead of request's subject\n",
 
180
" -utf8           - input characters are UTF8 (default ASCII)\n",
 
181
" -multivalue-rdn - enable support for multivalued RDNs\n",
175
182
" -extensions ..  - Extension section (override value in config file)\n",
176
183
" -extfile file   - Configuration file with X509v3 extentions to add\n",
177
184
" -crlexts ..     - CRL extension section (override value in config file)\n",
189
196
extern int EF_ALIGNMENT;
190
197
#endif
191
198
 
192
 
static void lookup_fail(char *name,char *tag);
 
199
static void lookup_fail(const char *name, const char *tag);
193
200
static int certify(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
194
201
                   const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,CA_DB *db,
195
 
                   BIGNUM *serial, char *subj, int email_dn, char *startdate,
 
202
                   BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate,
196
203
                   char *enddate, long days, int batch, char *ext_sect, CONF *conf,
197
204
                   int verbose, unsigned long certopt, unsigned long nameopt,
198
 
                   int default_op, int ext_copy);
 
205
                   int default_op, int ext_copy, int selfsign);
199
206
static int certify_cert(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
200
207
                        const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
201
 
                        CA_DB *db, BIGNUM *serial, char *subj, int email_dn,
 
208
                        CA_DB *db, BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn,
202
209
                        char *startdate, char *enddate, long days, int batch,
203
210
                        char *ext_sect, CONF *conf,int verbose, unsigned long certopt,
204
211
                        unsigned long nameopt, int default_op, int ext_copy,
205
212
                        ENGINE *e);
206
213
static int certify_spkac(X509 **xret, char *infile,EVP_PKEY *pkey,X509 *x509,
207
214
                         const EVP_MD *dgst,STACK_OF(CONF_VALUE) *policy,
208
 
                         CA_DB *db, BIGNUM *serial,char *subj, int email_dn,
 
215
                         CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn, int email_dn,
209
216
                         char *startdate, char *enddate, long days, char *ext_sect,
210
217
                         CONF *conf, int verbose, unsigned long certopt, 
211
218
                         unsigned long nameopt, int default_op, int ext_copy);
212
219
static int fix_data(int nid, int *type);
213
220
static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext);
214
221
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
215
 
        STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,
 
222
        STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,char *subj,unsigned long chtype, int multirdn,
216
223
        int email_dn, char *startdate, char *enddate, long days, int batch,
217
224
        int verbose, X509_REQ *req, char *ext_sect, CONF *conf,
218
225
        unsigned long certopt, unsigned long nameopt, int default_op,
219
 
        int ext_copy);
 
226
        int ext_copy, int selfsign);
220
227
static int do_revoke(X509 *x509, CA_DB *db, int ext, char *extval);
221
228
static int get_certificate_status(const char *ser_status, CA_DB *db);
222
229
static int do_updatedb(CA_DB *db);
223
230
static int check_time_format(char *str);
224
231
char *make_revocation_str(int rev_type, char *rev_arg);
225
 
int make_revoked(X509_REVOKED *rev, char *str);
 
232
int make_revoked(X509_REVOKED *rev, const char *str);
226
233
int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str);
227
234
static CONF *conf=NULL;
228
235
static CONF *extconf=NULL;
272
279
        char *extensions=NULL;
273
280
        char *extfile=NULL;
274
281
        char *subj=NULL;
 
282
        unsigned long chtype = MBSTRING_ASC;
 
283
        int multirdn = 0;
275
284
        char *tmp_email_dn=NULL;
276
285
        char *crl_ext=NULL;
277
286
        int rev_type = REV_NONE;
286
295
        unsigned long nameopt = 0, certopt = 0;
287
296
        int default_op = 1;
288
297
        int ext_copy = EXT_COPY_NONE;
289
 
        X509 *x509=NULL;
 
298
        int selfsign = 0;
 
299
        X509 *x509=NULL, *x509p = NULL;
290
300
        X509 *x=NULL;
291
301
        BIO *in=NULL,*out=NULL,*Sout=NULL,*Cout=NULL;
292
302
        char *dbfile=NULL;
295
305
        X509_REVOKED *r=NULL;
296
306
        ASN1_TIME *tmptm;
297
307
        ASN1_INTEGER *tmpser;
298
 
        char **pp,*p,*f;
 
308
        char *f;
 
309
        const char *p, **pp;
299
310
        int i,j;
300
311
        const EVP_MD *dgst=NULL;
301
312
        STACK_OF(CONF_VALUE) *attribs=NULL;
350
361
                        subj= *(++argv);
351
362
                        /* preserve=1; */
352
363
                        }
 
364
                else if (strcmp(*argv,"-utf8") == 0)
 
365
                        chtype = MBSTRING_UTF8;
 
366
                else if (strcmp(*argv,"-create_serial") == 0)
 
367
                        create_ser = 1;
 
368
                else if (strcmp(*argv,"-multivalue-rdn") == 0)
 
369
                        multirdn=1;
353
370
                else if (strcmp(*argv,"-startdate") == 0)
354
371
                        {
355
372
                        if (--argc < 1) goto bad;
400
417
                        if (--argc < 1) goto bad;
401
418
                        certfile= *(++argv);
402
419
                        }
 
420
                else if (strcmp(*argv,"-selfsign") == 0)
 
421
                        selfsign=1;
403
422
                else if (strcmp(*argv,"-in") == 0)
404
423
                        {
405
424
                        if (--argc < 1) goto bad;
633
652
                ERR_clear_error();
634
653
        app_RAND_load_file(randfile, bio_err, 0);
635
654
 
 
655
        f = NCONF_get_string(conf, section, STRING_MASK);
 
656
        if (!f)
 
657
                ERR_clear_error();
 
658
 
 
659
        if(f && !ASN1_STRING_set_default_mask_asc(f)) {
 
660
                BIO_printf(bio_err, "Invalid global string mask setting %s\n", f);
 
661
                goto err;
 
662
        }
 
663
 
 
664
        if (chtype != MBSTRING_UTF8){
 
665
                f = NCONF_get_string(conf, section, UTF8_IN);
 
666
                if (!f)
 
667
                        ERR_clear_error();
 
668
                else if (!strcmp(f, "yes"))
 
669
                        chtype = MBSTRING_UTF8;
 
670
        }
 
671
 
636
672
        db_attr.unique_subject = 1;
637
 
        p = NCONF_get_string(conf, section, "unique_subject");
 
673
        p = NCONF_get_string(conf, section, ENV_UNIQUE_SUBJECT);
638
674
        if (p)
639
675
                {
640
676
#ifdef RL_DEBUG
641
677
                BIO_printf(bio_err, "DEBUG: unique_subject = \"%s\"\n", p);
642
678
#endif
643
 
                switch(*p)
644
 
                        {
645
 
                case 'f': /* false */
646
 
                case 'F': /* FALSE */
647
 
                case 'n': /* no */
648
 
                case 'N': /* NO */
649
 
                        db_attr.unique_subject = 0;
650
 
                        break;
651
 
                case 't': /* true */
652
 
                case 'T': /* TRUE */
653
 
                case 'y': /* yes */
654
 
                case 'Y': /* YES */
655
 
                default:
656
 
                        db_attr.unique_subject = 1;
657
 
                        break;
658
 
                        }
 
679
                db_attr.unique_subject = parse_yesno(p,1);
659
680
                }
660
681
        else
661
682
                ERR_clear_error();
699
720
        }
700
721
 
701
722
        /*****************************************************************/
702
 
        /* we definitely need a public key, so let's get it */
 
723
        /* we definitely need a private key, so let's get it */
703
724
 
704
725
        if ((keyfile == NULL) && ((keyfile=NCONF_get_string(conf,
705
726
                section,ENV_PRIVATE_KEY)) == NULL))
727
748
 
728
749
        /*****************************************************************/
729
750
        /* we need a certificate */
730
 
        if ((certfile == NULL) && ((certfile=NCONF_get_string(conf,
731
 
                section,ENV_CERTIFICATE)) == NULL))
 
751
        if (!selfsign || spkac_file || ss_cert_file || gencrl)
732
752
                {
733
 
                lookup_fail(section,ENV_CERTIFICATE);
734
 
                goto err;
735
 
                }
736
 
        x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
737
 
                "CA certificate");
738
 
        if (x509 == NULL)
739
 
                goto err;
 
753
                if ((certfile == NULL)
 
754
                        && ((certfile=NCONF_get_string(conf,
 
755
                                     section,ENV_CERTIFICATE)) == NULL))
 
756
                        {
 
757
                        lookup_fail(section,ENV_CERTIFICATE);
 
758
                        goto err;
 
759
                        }
 
760
                x509=load_cert(bio_err, certfile, FORMAT_PEM, NULL, e,
 
761
                        "CA certificate");
 
762
                if (x509 == NULL)
 
763
                        goto err;
740
764
 
741
 
        if (!X509_check_private_key(x509,pkey))
742
 
                {
743
 
                BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
744
 
                goto err;
 
765
                if (!X509_check_private_key(x509,pkey))
 
766
                        {
 
767
                        BIO_printf(bio_err,"CA certificate and CA private key do not match\n");
 
768
                        goto err;
 
769
                        }
745
770
                }
 
771
        if (!selfsign) x509p = x509;
746
772
 
747
773
        f=NCONF_get_string(conf,BASE_SECTION,ENV_PRESERVE);
748
774
        if (f == NULL)
856
882
        /* Lets check some fields */
857
883
        for (i=0; i<sk_num(db->db->data); i++)
858
884
                {
859
 
                pp=(char **)sk_value(db->db->data,i);
 
885
                pp=(const char **)sk_value(db->db->data,i);
860
886
                if ((pp[DB_type][0] != DB_TYPE_REV) &&
861
887
                        (pp[DB_rev_date][0] != '\0'))
862
888
                        {
869
895
                        BIO_printf(bio_err," in entry %d\n", i+1);
870
896
                        goto err;
871
897
                        }
872
 
                if (!check_time_format(pp[DB_exp_date]))
 
898
                if (!check_time_format((char *)pp[DB_exp_date]))
873
899
                        {
874
900
                        BIO_printf(bio_err,"entry %d: invalid expiry date\n",i+1);
875
901
                        goto err;
943
969
                        if (verbose) BIO_printf(bio_err,
944
970
                                "Done. %d entries marked as expired\n",i); 
945
971
                        }
946
 
                        goto err;
947
972
                }
948
973
 
949
974
        /*****************************************************************/
994
1019
                        }
995
1020
                }
996
1021
 
 
1022
        if ((md == NULL) && ((md=NCONF_get_string(conf,
 
1023
                section,ENV_DEFAULT_MD)) == NULL))
 
1024
                {
 
1025
                lookup_fail(section,ENV_DEFAULT_MD);
 
1026
                goto err;
 
1027
                }
 
1028
 
 
1029
        if ((dgst=EVP_get_digestbyname(md)) == NULL)
 
1030
                {
 
1031
                BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
 
1032
                goto err;
 
1033
                }
 
1034
 
997
1035
        if (req)
998
1036
                {
999
 
                if ((md == NULL) && ((md=NCONF_get_string(conf,
1000
 
                        section,ENV_DEFAULT_MD)) == NULL))
1001
 
                        {
1002
 
                        lookup_fail(section,ENV_DEFAULT_MD);
1003
 
                        goto err;
1004
 
                        }
1005
1037
                if ((email_dn == 1) && ((tmp_email_dn=NCONF_get_string(conf,
1006
1038
                        section,ENV_DEFAULT_EMAIL_DN)) != NULL ))
1007
1039
                        {
1008
1040
                        if(strcmp(tmp_email_dn,"no") == 0)
1009
1041
                                email_dn=0;
1010
1042
                        }
1011
 
                if ((dgst=EVP_get_digestbyname(md)) == NULL)
1012
 
                        {
1013
 
                        BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1014
 
                        goto err;
1015
 
                        }
1016
1043
                if (verbose)
1017
1044
                        BIO_printf(bio_err,"message digest is %s\n",
1018
1045
                                OBJ_nid2ln(dgst->type));
1131
1158
                        {
1132
1159
                        total++;
1133
1160
                        j=certify_spkac(&x,spkac_file,pkey,x509,dgst,attribs,db,
1134
 
                                serial,subj,email_dn,startdate,enddate,days,extensions,
 
1161
                                serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,extensions,
1135
1162
                                conf,verbose,certopt,nameopt,default_op,ext_copy);
1136
1163
                        if (j < 0) goto err;
1137
1164
                        if (j > 0)
1155
1182
                        {
1156
1183
                        total++;
1157
1184
                        j=certify_cert(&x,ss_cert_file,pkey,x509,dgst,attribs,
1158
 
                                db,serial,subj,email_dn,startdate,enddate,days,batch,
 
1185
                                db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
1159
1186
                                extensions,conf,verbose, certopt, nameopt,
1160
1187
                                default_op, ext_copy, e);
1161
1188
                        if (j < 0) goto err;
1174
1201
                if (infile != NULL)
1175
1202
                        {
1176
1203
                        total++;
1177
 
                        j=certify(&x,infile,pkey,x509,dgst,attribs,db,
1178
 
                                serial,subj,email_dn,startdate,enddate,days,batch,
 
1204
                        j=certify(&x,infile,pkey,x509p,dgst,attribs,db,
 
1205
                                serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
1179
1206
                                extensions,conf,verbose, certopt, nameopt,
1180
 
                                default_op, ext_copy);
 
1207
                                default_op, ext_copy, selfsign);
1181
1208
                        if (j < 0) goto err;
1182
1209
                        if (j > 0)
1183
1210
                                {
1194
1221
                for (i=0; i<argc; i++)
1195
1222
                        {
1196
1223
                        total++;
1197
 
                        j=certify(&x,argv[i],pkey,x509,dgst,attribs,db,
1198
 
                                serial,subj,email_dn,startdate,enddate,days,batch,
 
1224
                        j=certify(&x,argv[i],pkey,x509p,dgst,attribs,db,
 
1225
                                serial,subj,chtype,multirdn,email_dn,startdate,enddate,days,batch,
1199
1226
                                extensions,conf,verbose, certopt, nameopt,
1200
 
                                default_op, ext_copy);
 
1227
                                default_op, ext_copy, selfsign);
1201
1228
                        if (j < 0) goto err;
1202
1229
                        if (j > 0)
1203
1230
                                {
1248
1275
                        x=sk_X509_value(cert_sk,i);
1249
1276
 
1250
1277
                        j=x->cert_info->serialNumber->length;
1251
 
                        p=(char *)x->cert_info->serialNumber->data;
 
1278
                        p=(const char *)x->cert_info->serialNumber->data;
1252
1279
                        
1253
1280
                        if(strlen(outdir) >= (size_t)(j ? BSIZE-j*2-6 : BSIZE-8))
1254
1281
                                {
1369
1396
 
1370
1397
                for (i=0; i<sk_num(db->db->data); i++)
1371
1398
                        {
1372
 
                        pp=(char **)sk_value(db->db->data,i);
 
1399
                        pp=(const char **)sk_value(db->db->data,i);
1373
1400
                        if (pp[DB_type][0] == DB_TYPE_REV)
1374
1401
                                {
1375
1402
                                if ((r=X509_REVOKED_new()) == NULL) goto err;
1395
1422
 
1396
1423
                /* we now have a CRL */
1397
1424
                if (verbose) BIO_printf(bio_err,"signing CRL\n");
1398
 
                if (md != NULL)
1399
 
                        {
1400
 
                        if ((dgst=EVP_get_digestbyname(md)) == NULL)
1401
 
                                {
1402
 
                                BIO_printf(bio_err,"%s is an unsupported message digest type\n",md);
1403
 
                                goto err;
1404
 
                                }
1405
 
                        }
 
1425
#ifndef OPENSSL_NO_DSA
 
1426
                if (pkey->type == EVP_PKEY_DSA) 
 
1427
                        dgst=EVP_dss1();
1406
1428
                else
1407
 
                        {
1408
 
#ifndef OPENSSL_NO_DSA
1409
 
                        if (pkey->type == EVP_PKEY_DSA) 
1410
 
                                dgst=EVP_dss1();
1411
 
                        else
1412
 
#endif
1413
 
                                dgst=EVP_md5();
1414
 
                        }
 
1429
#endif
 
1430
#ifndef OPENSSL_NO_ECDSA
 
1431
                if (pkey->type == EVP_PKEY_EC)
 
1432
                        dgst=EVP_ecdsa();
 
1433
#endif
1415
1434
 
1416
1435
                /* Add any extensions asked for */
1417
1436
 
1498
1517
        BN_free(serial);
1499
1518
        free_index(db);
1500
1519
        EVP_PKEY_free(pkey);
1501
 
        X509_free(x509);
 
1520
        if (x509) X509_free(x509);
1502
1521
        X509_CRL_free(crl);
1503
1522
        NCONF_free(conf);
1504
1523
        OBJ_cleanup();
1506
1525
        OPENSSL_EXIT(ret);
1507
1526
        }
1508
1527
 
1509
 
static void lookup_fail(char *name, char *tag)
 
1528
static void lookup_fail(const char *name, const char *tag)
1510
1529
        {
1511
1530
        BIO_printf(bio_err,"variable lookup failed for %s::%s\n",name,tag);
1512
1531
        }
1513
1532
 
1514
1533
static int certify(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1515
1534
             const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1516
 
             BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
 
1535
             BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
1517
1536
             long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1518
1537
             unsigned long certopt, unsigned long nameopt, int default_op,
1519
 
             int ext_copy)
 
1538
             int ext_copy, int selfsign)
1520
1539
        {
1521
1540
        X509_REQ *req=NULL;
1522
1541
        BIO *in=NULL;
1541
1560
 
1542
1561
        BIO_printf(bio_err,"Check that the request matches the signature\n");
1543
1562
 
 
1563
        if (selfsign && !X509_REQ_check_private_key(req,pkey))
 
1564
                {
 
1565
                BIO_printf(bio_err,"Certificate request and CA private key do not match\n");
 
1566
                ok=0;
 
1567
                goto err;
 
1568
                }
1544
1569
        if ((pktmp=X509_REQ_get_pubkey(req)) == NULL)
1545
1570
                {
1546
1571
                BIO_printf(bio_err,"error unpacking public key\n");
1563
1588
        else
1564
1589
                BIO_printf(bio_err,"Signature ok\n");
1565
1590
 
1566
 
        ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj, email_dn,
 
1591
        ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn, email_dn,
1567
1592
                startdate,enddate,days,batch,verbose,req,ext_sect,lconf,
1568
 
                certopt, nameopt, default_op, ext_copy);
 
1593
                certopt, nameopt, default_op, ext_copy, selfsign);
1569
1594
 
1570
1595
err:
1571
1596
        if (req != NULL) X509_REQ_free(req);
1575
1600
 
1576
1601
static int certify_cert(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
1577
1602
             const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
1578
 
             BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
 
1603
             BIGNUM *serial, char *subj, unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
1579
1604
             long days, int batch, char *ext_sect, CONF *lconf, int verbose,
1580
1605
             unsigned long certopt, unsigned long nameopt, int default_op,
1581
1606
             int ext_copy, ENGINE *e)
1617
1642
        if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
1618
1643
                goto err;
1619
1644
 
1620
 
        ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
 
1645
        ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
1621
1646
                days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
1622
 
                ext_copy);
 
1647
                ext_copy, 0);
1623
1648
 
1624
1649
err:
1625
1650
        if (rreq != NULL) X509_REQ_free(rreq);
1629
1654
 
1630
1655
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
1631
1656
             STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
 
1657
             unsigned long chtype, int multirdn,
1632
1658
             int email_dn, char *startdate, char *enddate, long days, int batch,
1633
1659
             int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
1634
1660
             unsigned long certopt, unsigned long nameopt, int default_op,
1635
 
             int ext_copy)
 
1661
             int ext_copy, int selfsign)
1636
1662
        {
1637
1663
        X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
1638
1664
        ASN1_UTCTIME *tm,*tmptm;
1644
1670
        X509_NAME_ENTRY *tne,*push;
1645
1671
        EVP_PKEY *pktmp;
1646
1672
        int ok= -1,i,j,last,nid;
1647
 
        char *p;
 
1673
        const char *p;
1648
1674
        CONF_VALUE *cv;
1649
1675
        char *row[DB_NUMBER],**rrow=NULL,**irow=NULL;
1650
1676
        char buf[25];
1661
1687
 
1662
1688
        if (subj)
1663
1689
                {
1664
 
                X509_NAME *n = do_subject(subj, MBSTRING_ASC);
 
1690
                X509_NAME *n = parse_name(subj, chtype, multirdn);
1665
1691
 
1666
1692
                if (!n)
1667
1693
                        {
1736
1762
                }
1737
1763
 
1738
1764
        /* take a copy of the issuer name before we mess with it. */
1739
 
        CAname=X509_NAME_dup(x509->cert_info->subject);
 
1765
        if (selfsign)
 
1766
                CAname=X509_NAME_dup(name);
 
1767
        else
 
1768
                CAname=X509_NAME_dup(x509->cert_info->subject);
1740
1769
        if (CAname == NULL) goto err;
1741
1770
        str=str2=NULL;
1742
1771
 
1948
1977
 
1949
1978
        if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL)
1950
1979
                goto err;
1951
 
        if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
1952
 
                goto err;
 
1980
        if (selfsign)
 
1981
                {
 
1982
                if (!X509_set_issuer_name(ret,subject))
 
1983
                        goto err;
 
1984
                }
 
1985
        else
 
1986
                {
 
1987
                if (!X509_set_issuer_name(ret,X509_get_subject_name(x509)))
 
1988
                        goto err;
 
1989
                }
1953
1990
 
1954
1991
        if (strcmp(startdate,"today") == 0)
1955
1992
                X509_gmtime_adj(X509_get_notBefore(ret),0);
1984
2021
                ci->extensions = NULL;
1985
2022
 
1986
2023
                /* Initialize the context structure */
1987
 
                X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
 
2024
                if (selfsign)
 
2025
                        X509V3_set_ctx(&ctx, ret, ret, req, NULL, 0);
 
2026
                else
 
2027
                        X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0);
1988
2028
 
1989
2029
                if (extconf)
1990
2030
                        {
2051
2091
 
2052
2092
        BIO_printf(bio_err,"Certificate is to be certified until ");
2053
2093
        ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret));
2054
 
        if (days) BIO_printf(bio_err," (%d days)",days);
 
2094
        if (days) BIO_printf(bio_err," (%ld days)",days);
2055
2095
        BIO_printf(bio_err, "\n");
2056
2096
 
2057
2097
        if (!batch)
2078
2118
                EVP_PKEY_copy_parameters(pktmp,pkey);
2079
2119
        EVP_PKEY_free(pktmp);
2080
2120
#endif
 
2121
#ifndef OPENSSL_NO_ECDSA
 
2122
        if (pkey->type == EVP_PKEY_EC)
 
2123
                dgst = EVP_ecdsa();
 
2124
        pktmp = X509_get_pubkey(ret);
 
2125
        if (EVP_PKEY_missing_parameters(pktmp) &&
 
2126
                !EVP_PKEY_missing_parameters(pkey))
 
2127
                EVP_PKEY_copy_parameters(pktmp, pkey);
 
2128
        EVP_PKEY_free(pktmp);
 
2129
#endif
 
2130
 
2081
2131
 
2082
2132
        if (!X509_sign(ret,pkey,dgst))
2083
2133
                goto err;
2174
2224
 
2175
2225
static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509,
2176
2226
             const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
2177
 
             BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
 
2227
             BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate,
2178
2228
             long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt,
2179
2229
             unsigned long nameopt, int default_op, int ext_copy)
2180
2230
        {
2315
2365
 
2316
2366
        X509_REQ_set_pubkey(req,pktmp);
2317
2367
        EVP_PKEY_free(pktmp);
2318
 
        ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
 
2368
        ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,chtype,multirdn,email_dn,startdate,enddate,
2319
2369
                   days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op,
2320
 
                        ext_copy);
 
2370
                        ext_copy, 0);
2321
2371
err:
2322
2372
        if (req != NULL) X509_REQ_free(req);
2323
2373
        if (parms != NULL) CONF_free(parms);
2628
2678
        return (cnt);
2629
2679
        }
2630
2680
 
2631
 
static char *crl_reasons[] = {
 
2681
static const char *crl_reasons[] = {
2632
2682
        /* CRL reason strings */
2633
2683
        "unspecified",
2634
2684
        "keyCompromise",
2656
2706
 
2657
2707
char *make_revocation_str(int rev_type, char *rev_arg)
2658
2708
        {
2659
 
        char *reason = NULL, *other = NULL, *str;
 
2709
        char *other = NULL, *str;
 
2710
        const char *reason = NULL;
2660
2711
        ASN1_OBJECT *otmp;
2661
2712
        ASN1_UTCTIME *revtm = NULL;
2662
2713
        int i;
2750
2801
 */
2751
2802
 
2752
2803
 
2753
 
int make_revoked(X509_REVOKED *rev, char *str)
 
2804
int make_revoked(X509_REVOKED *rev, const char *str)
2754
2805
        {
2755
2806
        char *tmp = NULL;
2756
2807
        int reason_code = -1;
2804
2855
        return ret;
2805
2856
        }
2806
2857
 
2807
 
/*
2808
 
 * subject is expected to be in the format /type0=value0/type1=value1/type2=...
2809
 
 * where characters may be escaped by \
2810
 
 */
2811
 
X509_NAME *do_subject(char *subject, long chtype)
2812
 
        {
2813
 
        size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */
2814
 
        char *buf = OPENSSL_malloc(buflen);
2815
 
        size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
2816
 
        char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *));
2817
 
        char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *));
2818
 
 
2819
 
        char *sp = subject, *bp = buf;
2820
 
        int i, ne_num = 0;
2821
 
 
2822
 
        X509_NAME *n = NULL;
2823
 
        int nid;
2824
 
 
2825
 
        if (!buf || !ne_types || !ne_values)
2826
 
        {
2827
 
                BIO_printf(bio_err, "malloc error\n");
2828
 
                goto error;
2829
 
        }
2830
 
 
2831
 
        if (*subject != '/')
2832
 
        {
2833
 
                BIO_printf(bio_err, "Subject does not start with '/'.\n");
2834
 
                goto error;
2835
 
        }
2836
 
        sp++; /* skip leading / */
2837
 
 
2838
 
        while (*sp)
2839
 
                {
2840
 
                /* collect type */
2841
 
                ne_types[ne_num] = bp;
2842
 
                while (*sp)
2843
 
                        {
2844
 
                        if (*sp == '\\') /* is there anything to escape in the type...? */
2845
 
                                {
2846
 
                                if (*++sp)
2847
 
                                        *bp++ = *sp++;
2848
 
                                else
2849
 
                                        {
2850
 
                                        BIO_printf(bio_err, "escape character at end of string\n");
2851
 
                                        goto error;
2852
 
                                        }
2853
 
                                }
2854
 
                        else if (*sp == '=')
2855
 
                                {
2856
 
                                sp++;
2857
 
                                *bp++ = '\0';
2858
 
                                break;
2859
 
                                }
2860
 
                        else
2861
 
                                *bp++ = *sp++;
2862
 
                        }
2863
 
                if (!*sp)
2864
 
                        {
2865
 
                        BIO_printf(bio_err, "end of string encountered while processing type of subject name element #%d\n", ne_num);
2866
 
                        goto error;
2867
 
                        }
2868
 
                ne_values[ne_num] = bp;
2869
 
                while (*sp)
2870
 
                        {
2871
 
                        if (*sp == '\\')
2872
 
                                {
2873
 
                                if (*++sp)
2874
 
                                        *bp++ = *sp++;
2875
 
                                else
2876
 
                                        {
2877
 
                                        BIO_printf(bio_err, "escape character at end of string\n");
2878
 
                                        goto error;
2879
 
                                        }
2880
 
                                }
2881
 
                        else if (*sp == '/')
2882
 
                                {
2883
 
                                sp++;
2884
 
                                break;
2885
 
                                }
2886
 
                        else
2887
 
                                *bp++ = *sp++;
2888
 
                        }
2889
 
                *bp++ = '\0';
2890
 
                ne_num++;
2891
 
                }
2892
 
 
2893
 
        if (!(n = X509_NAME_new()))
2894
 
                goto error;
2895
 
 
2896
 
        for (i = 0; i < ne_num; i++)
2897
 
                {
2898
 
                if ((nid=OBJ_txt2nid(ne_types[i])) == NID_undef)
2899
 
                        {
2900
 
                        BIO_printf(bio_err, "Subject Attribute %s has no known NID, skipped\n", ne_types[i]);
2901
 
                        continue;
2902
 
                        }
2903
 
 
2904
 
                if (!*ne_values[i])
2905
 
                        {
2906
 
                        BIO_printf(bio_err, "No value provided for Subject Attribute %s, skipped\n", ne_types[i]);
2907
 
                        continue;
2908
 
                        }
2909
 
 
2910
 
                if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char*)ne_values[i], -1,-1,0))
2911
 
                        goto error;
2912
 
                }
2913
 
 
2914
 
        OPENSSL_free(ne_values);
2915
 
        OPENSSL_free(ne_types);
2916
 
        OPENSSL_free(buf);
2917
 
        return n;
2918
 
 
2919
 
error:
2920
 
        X509_NAME_free(n);
2921
 
        if (ne_values)
2922
 
                OPENSSL_free(ne_values);
2923
 
        if (ne_types)
2924
 
                OPENSSL_free(ne_types);
2925
 
        if (buf)
2926
 
                OPENSSL_free(buf);
2927
 
        return NULL;
2928
 
}
2929
 
 
2930
2858
int old_entry_print(BIO *bp, ASN1_OBJECT *obj, ASN1_STRING *str)
2931
2859
        {
2932
2860
        char buf[25],*pbuf, *p;
2966
2894
        return 1;
2967
2895
        }
2968
2896
 
2969
 
int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, char *str)
 
2897
int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold, ASN1_GENERALIZEDTIME **pinvtm, const char *str)
2970
2898
        {
2971
2899
        char *tmp = NULL;
2972
2900
        char *rtime_str, *reason_str = NULL, *arg_str = NULL, *p;
2973
2901
        int reason_code = -1;
2974
 
        int i, ret = 0;
 
2902
        int ret = 0;
 
2903
        unsigned int i;
2975
2904
        ASN1_OBJECT *hold = NULL;
2976
2905
        ASN1_GENERALIZEDTIME *comp_time = NULL;
2977
2906
        tmp = BUF_strdup(str);