📄 ca.c
字号:
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)); if (subject == NULL) goto err; } if (verbose) BIO_printf(bio_err,"The subject name appears to be ok, checking data base for clashes\n"); row[DB_name]=X509_NAME_oneline(subject,NULL,0); if (BN_is_zero(serial)) row[DB_serial]=BUF_strdup("00"); else row[DB_serial]=BN_bn2hex(serial); if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) { BIO_printf(bio_err,"Memory allocation failure\n"); goto err; } rrow=TXT_DB_get_by_index(db,DB_name,row); if (rrow != NULL) { BIO_printf(bio_err,"ERROR:There is already a certificate for %s\n", row[DB_name]); } else { rrow=TXT_DB_get_by_index(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;#ifdef X509_V3 /* Make it an X509 v3 certificate. */ if (!X509_set_version(x509,2)) goto err;#endif if (BN_to_ASN1_INTEGER(serial,ci->serialNumber) == NULL) goto err; if (!X509_set_issuer_name(ret,X509_get_subject_name(x509))) goto err; BIO_printf(bio_err,"Certificate is to be certified until "); if (strcmp(startdate,"today") == 0) X509_gmtime_adj(X509_get_notBefore(ret),0); else ASN1_UTCTIME_set_string(X509_get_notBefore(ret),startdate); if (enddate == NULL) X509_gmtime_adj(X509_get_notAfter(ret),(long)60*60*24*days); else ASN1_UTCTIME_set_string(X509_get_notAfter(ret),enddate); ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret)); if(days) BIO_printf(bio_err," (%d days)",days); BIO_printf(bio_err, "\n"); if (!X509_set_subject_name(ret,subject)) goto err; pktmp=X509_REQ_get_pubkey(req); i = X509_set_pubkey(ret,pktmp); EVP_PKEY_free(pktmp); if (!i) goto err; /* Lets add the extensions, if there are any */ if (ext_sect) { X509V3_CTX ctx; if (ci->version == NULL) if ((ci->version=ASN1_INTEGER_new()) == NULL) goto err; ASN1_INTEGER_set(ci->version,2); /* version 3 certificate */ /* Free the current entries if any, there should not * be any I believe */ if (ci->extensions != NULL) sk_X509_EXTENSION_pop_free(ci->extensions, X509_EXTENSION_free); ci->extensions = NULL; X509V3_set_ctx(&ctx, x509, ret, req, NULL, 0); X509V3_set_conf_lhash(&ctx, lconf); if(!X509V3_EXT_add_conf(lconf, &ctx, ext_sect, ret)) goto err; } if (!batch) { BIO_printf(bio_err,"Sign the certificate? [y/n]:"); (void)BIO_flush(bio_err); buf[0]='\0'; fgets(buf,sizeof(buf)-1,stdin); if (!((buf[0] == 'y') || (buf[0] == 'Y'))) { BIO_printf(bio_err,"CERTIFICATE WILL NOT BE CERTIFIED\n"); ok=0; goto err; } }#ifndef NO_DSA if (pkey->type == EVP_PKEY_DSA) dgst=EVP_dss1(); pktmp=X509_get_pubkey(ret); if (EVP_PKEY_missing_parameters(pktmp) && !EVP_PKEY_missing_parameters(pkey)) EVP_PKEY_copy_parameters(pktmp,pkey); EVP_PKEY_free(pktmp);#endif if (!X509_sign(ret,pkey,dgst)) goto err; /* We now just add it to the database */ row[DB_type]=(char *)OPENSSL_malloc(2); tm=X509_get_notAfter(ret); row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1); memcpy(row[DB_exp_date],tm->data,tm->length); row[DB_exp_date][tm->length]='\0'; row[DB_rev_date]=NULL; /* row[DB_serial] done already */ row[DB_file]=(char *)OPENSSL_malloc(8); /* row[DB_name] done already */ if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) || (row[DB_file] == NULL)) { BIO_printf(bio_err,"Memory allocation failure\n"); goto err; } strcpy(row[DB_file],"unknown"); row[DB_type][0]='V'; row[DB_type][1]='\0'; if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL) { BIO_printf(bio_err,"Memory allocation failure\n"); goto err; } for (i=0; i<DB_NUMBER; i++) { irow[i]=row[i]; row[i]=NULL; } irow[DB_NUMBER]=NULL; if (!TXT_DB_insert(db,irow)) { BIO_printf(bio_err,"failed to update database\n"); BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error); goto err; } ok=1;err: for (i=0; i<DB_NUMBER; i++) if (row[i] != NULL) OPENSSL_free(row[i]); if (CAname != NULL) X509_NAME_free(CAname); if (subject != NULL) X509_NAME_free(subject); if (tmptm != NULL) ASN1_UTCTIME_free(tmptm); if (ok <= 0) { if (ret != NULL) X509_free(ret); ret=NULL; } else *xret=ret; return(ok); }static void write_new_certificate(BIO *bp, X509 *x, int output_der, int notext) { if (output_der) { (void)i2d_X509_bio(bp,x); return; }#if 0 /* ??? Not needed since X509_print prints all this stuff anyway */ f=X509_NAME_oneline(X509_get_issuer_name(x),buf,256); BIO_printf(bp,"issuer :%s\n",f); f=X509_NAME_oneline(X509_get_subject_name(x),buf,256); BIO_printf(bp,"subject:%s\n",f); BIO_puts(bp,"serial :"); i2a_ASN1_INTEGER(bp,x->cert_info->serialNumber); BIO_puts(bp,"\n\n");#endif if(!notext)X509_print(bp,x); PEM_write_bio_X509(bp,x); }static int certify_spkac(X509 **xret, char *infile, EVP_PKEY *pkey, X509 *x509, const EVP_MD *dgst, STACK_OF(CONF_VALUE) *policy, TXT_DB *db, BIGNUM *serial, char *startdate, char *enddate, int days, char *ext_sect, LHASH *lconf, int verbose) { STACK_OF(CONF_VALUE) *sk=NULL; LHASH *parms=NULL; X509_REQ *req=NULL; CONF_VALUE *cv=NULL; NETSCAPE_SPKI *spki = NULL; X509_REQ_INFO *ri; char *type,*buf; EVP_PKEY *pktmp=NULL; X509_NAME *n=NULL; X509_NAME_ENTRY *ne=NULL; int ok= -1,i,j; long errline; int nid; /* * Load input file into a hash table. (This is just an easy * way to read and parse the file, then put it into a convenient * STACK format). */ parms=CONF_load(NULL,infile,&errline); if (parms == NULL) { BIO_printf(bio_err,"error on line %ld of %s\n",errline,infile); ERR_print_errors(bio_err); goto err; } sk=CONF_get_section(parms, "default"); if (sk_CONF_VALUE_num(sk) == 0) { BIO_printf(bio_err, "no name/value pairs found in %s\n", infile); CONF_free(parms); goto err; } /* * Now create a dummy X509 request structure. We don't actually * have an X509 request, but we have many of the components * (a public key, various DN components). The idea is that we * put these components into the right X509 request structure * and we can use the same code as if you had a real X509 request. */ req=X509_REQ_new(); if (req == NULL) { ERR_print_errors(bio_err); goto err; } /* * Build up the subject name set. */ ri=req->req_info; n = ri->subject; for (i = 0; ; i++) { if (sk_CONF_VALUE_num(sk) <= i) break; cv=sk_CONF_VALUE_value(sk,i); type=cv->name; /* Skip past any leading X. X: X, etc to allow for * multiple instances */ for(buf = cv->name; *buf ; buf++) if ((*buf == ':') || (*buf == ',') || (*buf == '.')) { buf++; if(*buf) type = buf; break; } buf=cv->value; if ((nid=OBJ_txt2nid(type)) == NID_undef) { if (strcmp(type, "SPKAC") == 0) { spki = NETSCAPE_SPKI_b64_decode(cv->value, -1); if (spki == NULL) { BIO_printf(bio_err,"unable to load Netscape SPKAC structure\n"); ERR_print_errors(bio_err); goto err; } } continue; } j=ASN1_PRINTABLE_type((unsigned char *)buf,-1); if (fix_data(nid, &j) == 0) { BIO_printf(bio_err, "invalid characters in string %s\n",buf); goto err; } if ((ne=X509_NAME_ENTRY_create_by_NID(&ne,nid,j, (unsigned char *)buf, strlen(buf))) == NULL) goto err; if (!X509_NAME_add_entry(n,ne,-1, 0)) goto err; } if (spki == NULL) { BIO_printf(bio_err,"Netscape SPKAC structure not found in %s\n", infile); goto err; } /* * Now extract the key from the SPKI structure. */ BIO_printf(bio_err,"Check that the SPKAC request matches the signature\n"); if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL) { BIO_printf(bio_err,"error unpacking SPKAC public key\n"); goto err; } j = NETSCAPE_SPKI_verify(spki, pktmp); if (j <= 0) { BIO_printf(bio_err,"signature verification failed on SPKAC public key\n"); goto err; } BIO_printf(bio_err,"Signature ok\n"); X509_REQ_set_pubkey(req,pktmp); EVP_PKEY_free(pktmp); ok=do_body(xret,pkey,x509,dgst,policy,db,serial,startdate,enddate, days,1,verbose,req,ext_sect,lconf);err: if (req != NULL) X509_REQ_free(req); if (parms != NULL) CONF_free(parms); if (spki != NULL) NETSCAPE_SPKI_free(spki); if (ne != NULL) X509_NAME_ENTRY_free(ne); return(ok); }static int fix_data(int nid, int *type) { if (nid == NID_pkcs9_emailAddress) *type=V_ASN1_IA5STRING; if ((nid == NID_commonName) && (*type == V_ASN1_IA5STRING)) *type=V_ASN1_T61STRING; if ((nid == NID_pkcs9_challengePassword) && (*type == V_ASN1_IA5STRING)) *type=V_ASN1_T61STRING; if ((nid == NID_pkcs9_unstructuredName) && (*type == V_ASN1_T61STRING)) return(0); if (nid == NID_pkcs9_unstructuredName) *type=V_ASN1_IA5STRING; return(1); }static int check_time_format(char *str) { ASN1_UTCTIME tm; tm.data=(unsigned char *)str; tm.length=strlen(str); tm.type=V_ASN1_UTCTIME; return(ASN1_UTCTIME_check(&tm)); }static int do_revoke(X509 *x509, TXT_DB *db){ ASN1_UTCTIME *tm=NULL, *revtm=NULL; char *row[DB_NUMBER],**rrow,**irow; BIGNUM *bn = NULL; int ok=-1,i; for (i=0; i<DB_NUMBER; i++) row[i]=NULL; row[DB_name]=X509_NAME_oneline(X509_get_subject_name(x509),NULL,0); bn = ASN1_INTEGER_to_BN(X509_get_serialNumber(x509),NULL); if (BN_is_zero(bn)) row[DB_serial]=BUF_strdup("00"); else row[DB_serial]=BN_bn2hex(bn); BN_free(bn); if ((row[DB_name] == NULL) || (row[DB_serial] == NULL)) { BIO_printf(bio_err,"Memory allocation failure\n"); goto err; } /* We have to lookup by serial number because name lookup * skips revoked certs */ rrow=TXT_DB_get_by_index(db,DB_serial,row); if (rrow == NULL) { BIO_printf(bio_err,"Adding Entry to DB for %s\n", row[DB_name]); /* We now just add it to the database */ row[DB_type]=(char *)OPENSSL_malloc(2); tm=X509_get_notAfter(x509); row[DB_exp_date]=(char *)OPENSSL_malloc(tm->length+1); memcpy(row[DB_exp_date],tm->data,tm->length); row[DB_exp_date][tm->length]='\0'; row[DB_rev_date]=NULL; /* row[DB_serial] done already */ row[DB_file]=(char *)OPENSSL_malloc(8); /* row[DB_name] done already */ if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) || (row[DB_file] == NULL)) { BIO_printf(bio_err,"Memory allocation failure\n"); goto err; } strcpy(row[DB_file],"unknown"); row[DB_type][0]='V'; row[DB_type][1]='\0'; if ((irow=(char **)OPENSSL_malloc(sizeof(char *)*(DB_NUMBER+1))) == NULL) { BIO_printf(bio_err,"Memory allocation failure\n"); goto err; } for (i=0; i<DB_NUMBER; i++) { irow[i]=row[i]; row[i]=NULL; } irow[DB_NUMBER]=NULL; if (!TXT_DB_insert(db,irow)) { BIO_printf(bio_err,"failed to update database\n"); BIO_printf(bio_err,"TXT_DB error number %ld\n",db->error); goto err; } /* Revoke Certificate */ ok = do_revoke(x509,db); goto err; } else if (index_name_cmp(row,rrow)) { BIO_printf(bio_err,"ERROR:name does not match %s\n", row[DB_name]); goto err; } else if (rrow[DB_type][0]=='R') { BIO_printf(bio_err,"ERROR:Already revoked, serial number %s\n", row[DB_serial]); goto err; } else { BIO_printf(bio_err,"Revoking Certificate %s.\n", rrow[DB_serial]); revtm = ASN1_UTCTIME_new(); revtm=X509_gmtime_adj(revtm,0); rrow[DB_type][0]='R'; rrow[DB_type][1]='\0'; rrow[DB_rev_date]=(char *)OPENSSL_malloc(revtm->length+1); memcpy(rrow[DB_rev_date],revtm->data,revtm->length); rrow[DB_rev_date][revtm->length]='\0'; ASN1_UTCTIME_free(revtm); } ok=1;err: for (i=0; i<DB_NUMBER; i++) { if (row[i] != NULL) OPENSSL_free(row[i]); } return(ok);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -