- const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, CA_DB *db,
- BIGNUM *serial, char *subj, int email_dn, char *startdate, char *enddate,
- long days, int batch, char *ext_sect, CONF *lconf, int verbose,
- unsigned long certopt, unsigned long nameopt, int default_op,
- int ext_copy, ENGINE *e)
- {
- X509 *req=NULL;
- X509_REQ *rreq=NULL;
- EVP_PKEY *pktmp=NULL;
- int ok= -1,i;
-
- if ((req=load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
- goto err;
- if (verbose)
- X509_print(bio_err,req);
-
- BIO_printf(bio_err,"Check that the request matches the signature\n");
-
- if ((pktmp=X509_get_pubkey(req)) == NULL)
- {
- BIO_printf(bio_err,"error unpacking public key\n");
- goto err;
- }
- i=X509_verify(req,pktmp);
- EVP_PKEY_free(pktmp);
- if (i < 0)
- {
- ok=0;
- BIO_printf(bio_err,"Signature verification problems....\n");
- goto err;
- }
- if (i == 0)
- {
- ok=0;
- BIO_printf(bio_err,"Signature did not match the certificate\n");
- goto err;
- }
- else
- BIO_printf(bio_err,"Signature ok\n");
-
- if ((rreq=X509_to_X509_REQ(req,NULL,EVP_md5())) == NULL)
- goto err;
-
- ok=do_body(xret,pkey,x509,dgst,policy,db,serial,subj,email_dn,startdate,enddate,
- days,batch,verbose,rreq,ext_sect,lconf, certopt, nameopt, default_op,
- ext_copy, 0);
-
-err:
- if (rreq != NULL) X509_REQ_free(rreq);
- if (req != NULL) X509_free(req);
- return(ok);
- }
-
-static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst,
- STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial, char *subj,
- int email_dn, char *startdate, char *enddate, long days, int batch,
- int verbose, X509_REQ *req, char *ext_sect, CONF *lconf,
- unsigned long certopt, unsigned long nameopt, int default_op,
- int ext_copy, int selfsign)
- {
- X509_NAME *name=NULL,*CAname=NULL,*subject=NULL, *dn_subject=NULL;
- ASN1_UTCTIME *tm,*tmptm;
- ASN1_STRING *str,*str2;
- ASN1_OBJECT *obj;
- X509 *ret=NULL;
- X509_CINF *ci;
- X509_NAME_ENTRY *ne;
- X509_NAME_ENTRY *tne,*push;
- EVP_PKEY *pktmp;
- int ok= -1,i,j,last,nid;
- char *p;
- CONF_VALUE *cv;
- char *row[DB_NUMBER],**rrow=NULL,**irow=NULL;
- char buf[25];
-
- tmptm=ASN1_UTCTIME_new();
- if (tmptm == NULL)
- {
- BIO_printf(bio_err,"malloc error\n");
- return(0);
- }
-
- for (i=0; i<DB_NUMBER; i++)
- row[i]=NULL;
-
- if (subj)
- {
- X509_NAME *n = do_subject(subj, MBSTRING_ASC);
-
- if (!n)
- {
- ERR_print_errors(bio_err);
- goto err;
- }
- X509_REQ_set_subject_name(req,n);
- req->req_info->enc.modified = 1;
- X509_NAME_free(n);
- }
-
- if (default_op)
- BIO_printf(bio_err,"The Subject's Distinguished Name is as follows\n");
-
- name=X509_REQ_get_subject_name(req);
- for (i=0; i<X509_NAME_entry_count(name); i++)
- {
- ne= X509_NAME_get_entry(name,i);
- str=X509_NAME_ENTRY_get_data(ne);
- obj=X509_NAME_ENTRY_get_object(ne);
-
- if (msie_hack)
- {
- /* assume all type should be strings */
- nid=OBJ_obj2nid(ne->object);
-
- if (str->type == V_ASN1_UNIVERSALSTRING)
- ASN1_UNIVERSALSTRING_to_string(str);
-
- if ((str->type == V_ASN1_IA5STRING) &&
- (nid != NID_pkcs9_emailAddress))
- str->type=V_ASN1_T61STRING;
-
- if ((nid == NID_pkcs9_emailAddress) &&
- (str->type == V_ASN1_PRINTABLESTRING))
- str->type=V_ASN1_IA5STRING;
- }
-
- /* If no EMAIL is wanted in the subject */
- if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
- continue;
-
- /* check some things */
- if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
- (str->type != V_ASN1_IA5STRING))
- {
- BIO_printf(bio_err,"\nemailAddress type needs to be of type IA5STRING\n");
- goto err;
- }
- if ((str->type != V_ASN1_BMPSTRING) && (str->type != V_ASN1_UTF8STRING))
- {
- j=ASN1_PRINTABLE_type(str->data,str->length);
- if ( ((j == V_ASN1_T61STRING) &&
- (str->type != V_ASN1_T61STRING)) ||
- ((j == V_ASN1_IA5STRING) &&
- (str->type == V_ASN1_PRINTABLESTRING)))
- {
- BIO_printf(bio_err,"\nThe string contains characters that are illegal for the ASN.1 type\n");
- goto err;
- }
- }
-
- if (default_op)
- old_entry_print(bio_err, obj, str);
- }
-
- /* Ok, now we check the 'policy' stuff. */
- if ((subject=X509_NAME_new()) == NULL)
- {
- BIO_printf(bio_err,"Memory allocation failure\n");
- goto err;
- }
-
- /* take a copy of the issuer name before we mess with it. */
- if (selfsign)
- CAname=X509_NAME_dup(name);
- else
- CAname=X509_NAME_dup(x509->cert_info->subject);
- if (CAname == NULL) goto err;
- str=str2=NULL;
-
- for (i=0; i<sk_CONF_VALUE_num(policy); i++)
- {
- cv=sk_CONF_VALUE_value(policy,i); /* get the object id */
- if ((j=OBJ_txt2nid(cv->name)) == NID_undef)
- {
- BIO_printf(bio_err,"%s:unknown object type in 'policy' configuration\n",cv->name);
- goto err;
- }
- obj=OBJ_nid2obj(j);
-
- last= -1;
- for (;;)
- {
- /* lookup the object in the supplied name list */
- j=X509_NAME_get_index_by_OBJ(name,obj,last);
- if (j < 0)
- {
- if (last != -1) break;
- tne=NULL;
- }
- else
- {
- tne=X509_NAME_get_entry(name,j);
- }
- last=j;
-
- /* depending on the 'policy', decide what to do. */
- push=NULL;
- if (strcmp(cv->value,"optional") == 0)
- {
- if (tne != NULL)
- push=tne;
- }
- else if (strcmp(cv->value,"supplied") == 0)
- {
- if (tne == NULL)
- {
- BIO_printf(bio_err,"The %s field needed to be supplied and was missing\n",cv->name);
- goto err;
- }
- else
- push=tne;
- }
- else if (strcmp(cv->value,"match") == 0)
- {
- int last2;
-
- if (tne == NULL)
- {
- BIO_printf(bio_err,"The mandatory %s field was missing\n",cv->name);
- goto err;
- }
-
- last2= -1;
-
-again2:
- j=X509_NAME_get_index_by_OBJ(CAname,obj,last2);
- if ((j < 0) && (last2 == -1))
- {
- BIO_printf(bio_err,"The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",cv->name);
- goto err;
- }
- if (j >= 0)
- {
- push=X509_NAME_get_entry(CAname,j);
- str=X509_NAME_ENTRY_get_data(tne);
- str2=X509_NAME_ENTRY_get_data(push);
- last2=j;
- if (ASN1_STRING_cmp(str,str2) != 0)
- goto again2;
- }
- if (j < 0)
- {
- BIO_printf(bio_err,"The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",cv->name,((str2 == NULL)?"NULL":(char *)str2->data),((str == NULL)?"NULL":(char *)str->data));
- goto err;
- }
- }
- else
- {
- BIO_printf(bio_err,"%s:invalid type in 'policy' configuration\n",cv->value);
- goto err;
- }
-
- if (push != NULL)
- {
- if (!X509_NAME_add_entry(subject,push, -1, 0))
- {
- if (push != NULL)
- X509_NAME_ENTRY_free(push);
- BIO_printf(bio_err,"Memory allocation failure\n");
- goto err;
- }
- }
- if (j < 0) break;
- }
- }
-
- if (preserve)
- {
- X509_NAME_free(subject);
- /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
- subject=X509_NAME_dup(name);
- if (subject == NULL) goto err;
- }
-
- if (verbose)
- BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n");
-
- /* Build the correct Subject if no e-mail is wanted in the subject */
- /* and add it later on because of the method extensions are added (altName) */
-
- if (email_dn)
- dn_subject = subject;
- else
- {
- X509_NAME_ENTRY *tmpne;
- /* Its best to dup the subject DN and then delete any email
- * addresses because this retains its structure.
- */
- if (!(dn_subject = X509_NAME_dup(subject)))
- {
- BIO_printf(bio_err,"Memory allocation failure\n");
- goto err;
- }
- while((i = X509_NAME_get_index_by_NID(dn_subject,
- NID_pkcs9_emailAddress, -1)) >= 0)
- {
- tmpne = X509_NAME_get_entry(dn_subject, i);
- X509_NAME_delete_entry(dn_subject, i);
- X509_NAME_ENTRY_free(tmpne);
- }
- }
-
- if (BN_is_zero(serial))
- row[DB_serial]=BUF_strdup("00");
- else
- row[DB_serial]=BN_bn2hex(serial);
- if (row[DB_serial] == NULL)
- {
- BIO_printf(bio_err,"Memory allocation failure\n");
- goto err;
- }
-
- if (db->attributes.unique_subject)
- {
- rrow=TXT_DB_get_by_index(db->db,DB_name,row);
- if (rrow != NULL)
- {
- BIO_printf(bio_err,
- "ERROR:There is already a certificate for %s\n",
- row[DB_name]);
- }
- }
- if (rrow == NULL)
- {
- rrow=TXT_DB_get_by_index(db->db,DB_serial,row);
- if (rrow != NULL)
- {
- BIO_printf(bio_err,"ERROR:Serial number %s has already been issued,\n",
- row[DB_serial]);
- BIO_printf(bio_err," check the database/serial_file for corruption\n");
- }
- }
-
- if (rrow != NULL)
- {
- BIO_printf(bio_err,
- "The matching entry has the following details\n");
- if (rrow[DB_type][0] == 'E')
- p="Expired";
- else if (rrow[DB_type][0] == 'R')
- p="Revoked";
- else if (rrow[DB_type][0] == 'V')
- p="Valid";
- else
- p="\ninvalid type, Data base error\n";
- BIO_printf(bio_err,"Type :%s\n",p);;
- if (rrow[DB_type][0] == 'R')
- {
- p=rrow[DB_exp_date]; if (p == NULL) p="undef";
- BIO_printf(bio_err,"Was revoked on:%s\n",p);
- }
- p=rrow[DB_exp_date]; if (p == NULL) p="undef";
- BIO_printf(bio_err,"Expires on :%s\n",p);
- p=rrow[DB_serial]; if (p == NULL) p="undef";
- BIO_printf(bio_err,"Serial Number :%s\n",p);
- p=rrow[DB_file]; if (p == NULL) p="undef";
- BIO_printf(bio_err,"File name :%s\n",p);
- p=rrow[DB_name]; if (p == NULL) p="undef";
- BIO_printf(bio_err,"Subject Name :%s\n",p);
- ok= -1; /* This is now a 'bad' error. */
- goto err;
- }
-
- /* We are now totally happy, lets make and sign the certificate */
- if (verbose)
- BIO_printf(bio_err,"Everything appears to be ok, creating and signing the certificate\n");
-
- if ((ret=X509_new()) == NULL) goto err;
- ci=ret->cert_info;
+ const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+ STACK_OF(CONF_VALUE) *policy, CA_DB *db,
+ BIGNUM *serial, char *subj, unsigned long chtype,
+ int multirdn, int email_dn, char *startdate,
+ char *enddate, long days, int batch, char *ext_sect,
+ CONF *lconf, int verbose, unsigned long certopt,
+ unsigned long nameopt, int default_op, int ext_copy,
+ ENGINE *e)
+{
+ X509 *req = NULL;
+ X509_REQ *rreq = NULL;
+ EVP_PKEY *pktmp = NULL;
+ int ok = -1, i;
+
+ if ((req =
+ load_cert(bio_err, infile, FORMAT_PEM, NULL, e, infile)) == NULL)
+ goto err;
+ if (verbose)
+ X509_print(bio_err, req);
+
+ BIO_printf(bio_err, "Check that the request matches the signature\n");
+
+ if ((pktmp = X509_get_pubkey(req)) == NULL) {
+ BIO_printf(bio_err, "error unpacking public key\n");
+ goto err;
+ }
+ i = X509_verify(req, pktmp);
+ EVP_PKEY_free(pktmp);
+ if (i < 0) {
+ ok = 0;
+ BIO_printf(bio_err, "Signature verification problems....\n");
+ goto err;
+ }
+ if (i == 0) {
+ ok = 0;
+ BIO_printf(bio_err, "Signature did not match the certificate\n");
+ goto err;
+ } else
+ BIO_printf(bio_err, "Signature ok\n");
+
+ if ((rreq = X509_to_X509_REQ(req, NULL, EVP_md5())) == NULL)
+ goto err;
+
+ ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, subj,
+ chtype, multirdn, email_dn, startdate, enddate, days, batch,
+ verbose, rreq, ext_sect, lconf, certopt, nameopt, default_op,
+ ext_copy, 0);
+
+ err:
+ if (rreq != NULL)
+ X509_REQ_free(rreq);
+ if (req != NULL)
+ X509_free(req);
+ return (ok);
+}
+
+static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
+ const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts,
+ STACK_OF(CONF_VALUE) *policy, CA_DB *db, BIGNUM *serial,
+ char *subj, unsigned long chtype, int multirdn,
+ int email_dn, char *startdate, char *enddate, long days,
+ int batch, int verbose, X509_REQ *req, char *ext_sect,
+ CONF *lconf, unsigned long certopt, unsigned long nameopt,
+ int default_op, int ext_copy, int selfsign)
+{
+ X509_NAME *name = NULL, *CAname = NULL, *subject = NULL;
+ ASN1_UTCTIME *tm, *tmptm;
+ ASN1_STRING *str, *str2;
+ ASN1_OBJECT *obj;
+ X509 *ret = NULL;
+ X509_CINF *ci;
+ X509_NAME_ENTRY *ne;
+ X509_NAME_ENTRY *tne, *push;
+ EVP_PKEY *pktmp;
+ int ok = -1, i, j, last, nid;
+ const char *p;
+ CONF_VALUE *cv;
+ OPENSSL_STRING row[DB_NUMBER];
+ OPENSSL_STRING *irow = NULL;
+ OPENSSL_STRING *rrow = NULL;
+ char buf[25];
+
+ tmptm = ASN1_UTCTIME_new();
+ if (tmptm == NULL) {
+ BIO_printf(bio_err, "malloc error\n");
+ return (0);
+ }
+
+ for (i = 0; i < DB_NUMBER; i++)
+ row[i] = NULL;
+
+ if (subj) {
+ X509_NAME *n = parse_name(subj, chtype, multirdn);
+
+ if (!n) {
+ ERR_print_errors(bio_err);
+ goto err;
+ }
+ X509_REQ_set_subject_name(req, n);
+ req->req_info->enc.modified = 1;
+ X509_NAME_free(n);
+ }
+
+ if (default_op)
+ BIO_printf(bio_err,
+ "The Subject's Distinguished Name is as follows\n");
+
+ name = X509_REQ_get_subject_name(req);
+ for (i = 0; i < X509_NAME_entry_count(name); i++) {
+ ne = X509_NAME_get_entry(name, i);
+ str = X509_NAME_ENTRY_get_data(ne);
+ obj = X509_NAME_ENTRY_get_object(ne);
+
+ if (msie_hack) {
+ /* assume all type should be strings */
+ nid = OBJ_obj2nid(ne->object);
+
+ if (str->type == V_ASN1_UNIVERSALSTRING)
+ ASN1_UNIVERSALSTRING_to_string(str);
+
+ if ((str->type == V_ASN1_IA5STRING) &&
+ (nid != NID_pkcs9_emailAddress))
+ str->type = V_ASN1_T61STRING;
+
+ if ((nid == NID_pkcs9_emailAddress) &&
+ (str->type == V_ASN1_PRINTABLESTRING))
+ str->type = V_ASN1_IA5STRING;
+ }
+
+ /* If no EMAIL is wanted in the subject */
+ if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) && (!email_dn))
+ continue;
+
+ /* check some things */
+ if ((OBJ_obj2nid(obj) == NID_pkcs9_emailAddress) &&
+ (str->type != V_ASN1_IA5STRING)) {
+ BIO_printf(bio_err,
+ "\nemailAddress type needs to be of type IA5STRING\n");
+ goto err;
+ }
+ if ((str->type != V_ASN1_BMPSTRING)
+ && (str->type != V_ASN1_UTF8STRING)) {
+ j = ASN1_PRINTABLE_type(str->data, str->length);
+ if (((j == V_ASN1_T61STRING) &&
+ (str->type != V_ASN1_T61STRING)) ||
+ ((j == V_ASN1_IA5STRING) &&
+ (str->type == V_ASN1_PRINTABLESTRING))) {
+ BIO_printf(bio_err,
+ "\nThe string contains characters that are illegal for the ASN.1 type\n");
+ goto err;
+ }
+ }
+
+ if (default_op)
+ old_entry_print(bio_err, obj, str);
+ }
+
+ /* Ok, now we check the 'policy' stuff. */
+ if ((subject = X509_NAME_new()) == NULL) {
+ BIO_printf(bio_err, "Memory allocation failure\n");
+ goto err;
+ }
+
+ /* take a copy of the issuer name before we mess with it. */
+ if (selfsign)
+ CAname = X509_NAME_dup(name);
+ else
+ CAname = X509_NAME_dup(x509->cert_info->subject);
+ if (CAname == NULL)
+ goto err;
+ str = str2 = NULL;
+
+ for (i = 0; i < sk_CONF_VALUE_num(policy); i++) {
+ cv = sk_CONF_VALUE_value(policy, i); /* get the object id */
+ if ((j = OBJ_txt2nid(cv->name)) == NID_undef) {
+ BIO_printf(bio_err,
+ "%s:unknown object type in 'policy' configuration\n",
+ cv->name);
+ goto err;
+ }
+ obj = OBJ_nid2obj(j);
+
+ last = -1;
+ for (;;) {
+ /* lookup the object in the supplied name list */
+ j = X509_NAME_get_index_by_OBJ(name, obj, last);
+ if (j < 0) {
+ if (last != -1)
+ break;
+ tne = NULL;
+ } else {
+ tne = X509_NAME_get_entry(name, j);
+ }
+ last = j;
+
+ /* depending on the 'policy', decide what to do. */
+ push = NULL;
+ if (strcmp(cv->value, "optional") == 0) {
+ if (tne != NULL)
+ push = tne;
+ } else if (strcmp(cv->value, "supplied") == 0) {
+ if (tne == NULL) {
+ BIO_printf(bio_err,
+ "The %s field needed to be supplied and was missing\n",
+ cv->name);
+ goto err;
+ } else
+ push = tne;
+ } else if (strcmp(cv->value, "match") == 0) {
+ int last2;
+
+ if (tne == NULL) {
+ BIO_printf(bio_err,
+ "The mandatory %s field was missing\n",
+ cv->name);
+ goto err;
+ }
+
+ last2 = -1;
+
+ again2:
+ j = X509_NAME_get_index_by_OBJ(CAname, obj, last2);
+ if ((j < 0) && (last2 == -1)) {
+ BIO_printf(bio_err,
+ "The %s field does not exist in the CA certificate,\nthe 'policy' is misconfigured\n",
+ cv->name);
+ goto err;
+ }
+ if (j >= 0) {
+ push = X509_NAME_get_entry(CAname, j);
+ str = X509_NAME_ENTRY_get_data(tne);
+ str2 = X509_NAME_ENTRY_get_data(push);
+ last2 = j;
+ if (ASN1_STRING_cmp(str, str2) != 0)
+ goto again2;
+ }
+ if (j < 0) {
+ BIO_printf(bio_err,
+ "The %s field needed to be the same in the\nCA certificate (%s) and the request (%s)\n",
+ cv->name,
+ ((str2 == NULL) ? "NULL" : (char *)str2->data),
+ ((str == NULL) ? "NULL" : (char *)str->data));
+ goto err;
+ }
+ } else {
+ BIO_printf(bio_err,
+ "%s:invalid type in 'policy' configuration\n",
+ cv->value);
+ goto err;
+ }
+
+ if (push != NULL) {
+ if (!X509_NAME_add_entry(subject, push, -1, 0)) {
+ BIO_printf(bio_err, "Memory allocation failure\n");
+ goto err;
+ }
+ }
+ if (j < 0)
+ break;
+ }
+ }
+
+ if (preserve) {
+ X509_NAME_free(subject);
+ /* subject=X509_NAME_dup(X509_REQ_get_subject_name(req)); */
+ subject = X509_NAME_dup(name);
+ if (subject == NULL)
+ goto err;
+ }
+
+ /* We are now totally happy, lets make and sign the certificate */
+ if (verbose)
+ BIO_printf(bio_err,
+ "Everything appears to be ok, creating and signing the certificate\n");
+
+ if ((ret = X509_new()) == NULL)
+ goto err;
+ ci = ret->cert_info;