📄 ca.c
字号:
ext_sect); ERR_print_errors(bio_err); goto err; } if (verbose) BIO_printf(bio_err, "Successfully added extensions from file.\n"); } else if (ext_sect) { /* We found extensions to be set from config file */ X509V3_set_nconf(&ctx, lconf); if(!X509V3_EXT_add_nconf(lconf, &ctx, ext_sect, ret)) { BIO_printf(bio_err, "ERROR: adding extensions in section %s\n", ext_sect); ERR_print_errors(bio_err); goto err; } if (verbose) BIO_printf(bio_err, "Successfully added extensions from config\n"); } } /* Copy extensions from request (if any) */ if (!copy_extensions(ret, req, ext_copy)) { BIO_printf(bio_err, "ERROR: adding extensions from request\n"); ERR_print_errors(bio_err); goto err; } /* Set the right value for the noemailDN option */ if( email_dn == 0 ) { if (!X509_set_subject_name(ret,dn_subject)) goto err; } if (!default_op) { BIO_printf(bio_err, "Certificate Details:\n"); /* Never print signature details because signature not present */ certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME; X509_print_ex(bio_err, ret, nameopt, certopt); } BIO_printf(bio_err,"Certificate is to be certified until "); ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ret)); if (days) BIO_printf(bio_err," (%ld days)",days); BIO_printf(bio_err, "\n"); 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 OPENSSL_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#ifndef OPENSSL_NO_ECDSA if (pkey->type == EVP_PKEY_EC) dgst = EVP_ecdsa(); 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]=X509_NAME_oneline(X509_get_subject_name(ret),NULL,0); if ((row[DB_type] == NULL) || (row[DB_exp_date] == NULL) || (row[DB_file] == NULL) || (row[DB_name] == NULL)) { BIO_printf(bio_err,"Memory allocation failure\n"); goto err; } BUF_strlcpy(row[DB_file],"unknown",8); 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->db,irow)) { BIO_printf(bio_err,"failed to update database\n"); BIO_printf(bio_err,"TXT_DB error number %ld\n",db->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 ((dn_subject != NULL) && !email_dn) X509_NAME_free(dn_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, CA_DB *db, BIGNUM *serial, char *subj,unsigned long chtype, int multirdn, int email_dn, char *startdate, char *enddate, long days, char *ext_sect, CONF *lconf, int verbose, unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy) { 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; } /* if ((nid == NID_pkcs9_emailAddress) && (email_dn == 0)) 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,subj,chtype,multirdn,email_dn,startdate,enddate, days,1,verbose,req,ext_sect,lconf, certopt, nameopt, default_op, ext_copy, 0);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, CA_DB *db, int type, char *value) { ASN1_UTCTIME *tm=NULL; char *row[DB_NUMBER],**rrow,**irow; char *rev_str = NULL; 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,DB_serial,row); if (rrow == NULL) { BIO_printf(bio_err,"Adding Entry with serial number %s to DB for %s\n", row[DB_serial], 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; } BUF_strlcpy(row[DB_file],"unknown",8); 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->db,irow)) { BIO_printf(bio_err,"failed to update database\n"); BIO_printf(bio_err,"TXT_DB error number %ld\n",db->db->error); goto err; } /* Revoke Certificate */ ok = do_revoke(x509,db, type, value); goto err; } else if (index_name_cmp((const char **)row,(const char **)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]); rev_str = make_revocation_str(type, value); if (!rev_str) { BIO_printf(bio_err, "Error in revocation arguments\n"); goto err; } rrow[DB_type][0]='R'; rrow[DB_type][1]='\0'; rrow[DB_rev_date] = rev_str; } ok=1;err: for (i=0; i<DB_NUMBER; i++) { if (row[i] != NULL) OPENSSL_free(row[i]); } return(ok); }static int get_certificate_status(const char *serial, CA_DB *db) { char *row[DB_NUMBER],**rrow; int ok=-1,i; /* Free Resources */ for (i=0; i<DB_NUMBER; i++) row[i]=NULL; /* Malloc needed char spaces */ row[DB_serial] = OPENSSL_malloc(strlen(serial) + 2); if (row[DB_serial] == NULL) { BIO_printf(bio_err,"Malloc failure\n"); goto err; } if (strlen(serial) % 2) { /* Set the first char to 0 */; row[DB_serial][0]='0'; /* Copy String from serial to row[DB_serial] */ memcpy(row[DB_serial]+1, serial, strlen(serial)); row[DB_serial][strlen(serial)+1]='\0'; } else { /* Copy String from serial to row[DB_serial] */ memcpy(row[DB_serial], serial, strlen(serial)); row[DB_serial][strlen(serial)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -