version 1.35, 2021/07/24 13:21:04 |
version 1.36, 2021/08/28 02:11:18 |
|
|
unsigned long chtype, int multirdn, int email_dn, char *startdate, |
unsigned long chtype, int multirdn, int email_dn, char *startdate, |
char *enddate, long days, char *ext_sect, CONF *conf, int verbose, |
char *enddate, long days, char *ext_sect, CONF *conf, int verbose, |
unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy); |
unsigned long certopt, unsigned long nameopt, int default_op, int ext_copy); |
static void write_new_certificate(BIO *bp, X509 *x, int output_der, |
static int write_new_certificate(BIO *bp, X509 *x, int output_der, |
int notext); |
int notext); |
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, |
static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, |
const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, |
const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, |
|
|
goto err; |
goto err; |
} |
} |
ca_config.md = (char *) OBJ_nid2sn(def_nid); |
ca_config.md = (char *) OBJ_nid2sn(def_nid); |
|
if (ca_config.md == NULL) |
|
goto err; |
} |
} |
if ((dgst = EVP_get_digestbyname(ca_config.md)) == NULL) { |
if ((dgst = EVP_get_digestbyname(ca_config.md)) == NULL) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
|
|
perror(pempath); |
perror(pempath); |
goto err; |
goto err; |
} |
} |
write_new_certificate(Cout, x, 0, ca_config.notext); |
if (!write_new_certificate(Cout, x, 0, |
write_new_certificate(Sout, x, output_der, |
ca_config.notext)) |
ca_config.notext); |
goto err; |
|
if (!write_new_certificate(Sout, x, output_der, |
|
ca_config.notext)) |
|
goto err; |
} |
} |
|
|
if (sk_X509_num(cert_sk)) { |
if (sk_X509_num(cert_sk)) { |
|
|
tmptm = ASN1_TIME_new(); |
tmptm = ASN1_TIME_new(); |
if (tmptm == NULL) |
if (tmptm == NULL) |
goto err; |
goto err; |
X509_gmtime_adj(tmptm, 0); |
if (X509_gmtime_adj(tmptm, 0) == NULL) { |
X509_CRL_set_lastUpdate(crl, tmptm); |
ASN1_TIME_free(tmptm); |
|
goto err; |
|
} |
|
if (!X509_CRL_set_lastUpdate(crl, tmptm)) { |
|
ASN1_TIME_free(tmptm); |
|
goto err; |
|
} |
if (X509_time_adj_ex(tmptm, ca_config.crldays, |
if (X509_time_adj_ex(tmptm, ca_config.crldays, |
ca_config.crlhours * 60 * 60 + ca_config.crlsec, NULL) == |
ca_config.crlhours * 60 * 60 + ca_config.crlsec, NULL) == |
NULL) { |
NULL) { |
BIO_puts(bio_err, "error setting CRL nextUpdate\n"); |
BIO_puts(bio_err, "error setting CRL nextUpdate\n"); |
|
ASN1_TIME_free(tmptm); |
goto err; |
goto err; |
} |
} |
X509_CRL_set_nextUpdate(crl, tmptm); |
if (!X509_CRL_set_nextUpdate(crl, tmptm)) { |
|
ASN1_TIME_free(tmptm); |
|
goto err; |
|
} |
ASN1_TIME_free(tmptm); |
ASN1_TIME_free(tmptm); |
|
|
for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { |
for (i = 0; i < sk_OPENSSL_PSTRING_num(db->db->data); i++) { |
|
|
serial = NULL; |
serial = NULL; |
if (tmpserial == NULL) |
if (tmpserial == NULL) |
goto err; |
goto err; |
X509_REVOKED_set_serialNumber(r, tmpserial); |
if (!X509_REVOKED_set_serialNumber(r, tmpserial)) { |
|
ASN1_INTEGER_free(tmpserial); |
|
goto err; |
|
} |
ASN1_INTEGER_free(tmpserial); |
ASN1_INTEGER_free(tmpserial); |
X509_CRL_add0_revoked(crl, r); |
if (!X509_CRL_add0_revoked(crl, r)) |
|
goto err; |
} |
} |
} |
} |
|
|
|
|
tmpserial = BN_to_ASN1_INTEGER(crlnumber, NULL); |
tmpserial = BN_to_ASN1_INTEGER(crlnumber, NULL); |
if (tmpserial == NULL) |
if (tmpserial == NULL) |
goto err; |
goto err; |
X509_CRL_add1_ext_i2d(crl, NID_crl_number, |
if (!X509_CRL_add1_ext_i2d(crl, NID_crl_number, |
tmpserial, 0, 0); |
tmpserial, 0, 0)) { |
|
ASN1_INTEGER_free(tmpserial); |
|
goto err; |
|
} |
ASN1_INTEGER_free(tmpserial); |
ASN1_INTEGER_free(tmpserial); |
crl_v2 = 1; |
crl_v2 = 1; |
if (!BN_add_word(crlnumber, 1)) |
if (!BN_add_word(crlnumber, 1)) |
|
|
ca_config.sigopts)) |
ca_config.sigopts)) |
goto err; |
goto err; |
|
|
PEM_write_bio_X509_CRL(Sout, crl); |
if (!PEM_write_bio_X509_CRL(Sout, crl)) |
|
goto err; |
|
|
if (crlnumberfile != NULL) /* Rename the crlnumber file */ |
if (crlnumberfile != NULL) /* Rename the crlnumber file */ |
if (!rotate_serial(crlnumberfile, "new", "old")) |
if (!rotate_serial(crlnumberfile, "new", "old")) |
|
|
infile); |
infile); |
goto err; |
goto err; |
} |
} |
if (verbose) |
if (verbose) { |
X509_REQ_print(bio_err, req); |
if (!X509_REQ_print(bio_err, req)) |
|
goto err; |
|
} |
|
|
BIO_printf(bio_err, "Check that the request matches the signature\n"); |
BIO_printf(bio_err, "Check that the request matches the signature\n"); |
|
|
|
|
if ((req = load_cert(bio_err, infile, FORMAT_PEM, NULL, |
if ((req = load_cert(bio_err, infile, FORMAT_PEM, NULL, |
infile)) == NULL) |
infile)) == NULL) |
goto err; |
goto err; |
if (verbose) |
if (verbose) { |
X509_print(bio_err, req); |
if (!X509_print(bio_err, req)) |
|
goto err; |
|
} |
|
|
BIO_printf(bio_err, "Check that the request matches the signature\n"); |
BIO_printf(bio_err, "Check that the request matches the signature\n"); |
|
|
|
|
ERR_print_errors(bio_err); |
ERR_print_errors(bio_err); |
goto err; |
goto err; |
} |
} |
X509_REQ_set_subject_name(req, n); |
if (!X509_REQ_set_subject_name(req, n)) { |
|
X509_NAME_free(n); |
|
goto err; |
|
} |
req->req_info->enc.modified = 1; |
req->req_info->enc.modified = 1; |
X509_NAME_free(n); |
X509_NAME_free(n); |
} |
} |
|
|
name = X509_REQ_get_subject_name(req); |
name = X509_REQ_get_subject_name(req); |
for (i = 0; i < X509_NAME_entry_count(name); i++) { |
for (i = 0; i < X509_NAME_entry_count(name); i++) { |
ne = X509_NAME_get_entry(name, i); |
ne = X509_NAME_get_entry(name, i); |
|
if (ne == NULL) |
|
goto err; |
str = X509_NAME_ENTRY_get_data(ne); |
str = X509_NAME_ENTRY_get_data(ne); |
|
if (str == NULL) |
|
goto err; |
obj = X509_NAME_ENTRY_get_object(ne); |
obj = X509_NAME_ENTRY_get_object(ne); |
|
if (obj == NULL) |
|
goto err; |
|
|
if (ca_config.msie_hack) { |
if (ca_config.msie_hack) { |
/* assume all type should be strings */ |
/* assume all type should be strings */ |
nid = OBJ_obj2nid(ne->object); |
nid = OBJ_obj2nid(ne->object); |
|
if (nid == NID_undef) |
|
goto err; |
|
|
if (str->type == V_ASN1_UNIVERSALSTRING) |
if (str->type == V_ASN1_UNIVERSALSTRING) |
ASN1_UNIVERSALSTRING_to_string(str); |
ASN1_UNIVERSALSTRING_to_string(str); |
|
|
goto err; |
goto err; |
} |
} |
obj = OBJ_nid2obj(j); |
obj = OBJ_nid2obj(j); |
|
if (obj == NULL) |
|
goto err; |
|
|
last = -1; |
last = -1; |
for (;;) { |
for (;;) { |
|
|
tne = NULL; |
tne = NULL; |
} else { |
} else { |
tne = X509_NAME_get_entry(name, j); |
tne = X509_NAME_get_entry(name, j); |
|
if (tne == NULL) |
|
goto err; |
} |
} |
last = j; |
last = j; |
|
|
|
|
} |
} |
if (j >= 0) { |
if (j >= 0) { |
push = X509_NAME_get_entry(CAname, j); |
push = X509_NAME_get_entry(CAname, j); |
|
if (push == NULL) |
|
goto err; |
str = X509_NAME_ENTRY_get_data(tne); |
str = X509_NAME_ENTRY_get_data(tne); |
|
if (str == NULL) |
|
goto err; |
str2 = X509_NAME_ENTRY_get_data(push); |
str2 = X509_NAME_ENTRY_get_data(push); |
|
if (str2 == NULL) |
|
goto err; |
last2 = j; |
last2 = j; |
if (ASN1_STRING_cmp(str, str2) != 0) |
if (ASN1_STRING_cmp(str, str2) != 0) |
goto again2; |
goto again2; |
|
|
while ((i = X509_NAME_get_index_by_NID(dn_subject, |
while ((i = X509_NAME_get_index_by_NID(dn_subject, |
NID_pkcs9_emailAddress, -1)) >= 0) { |
NID_pkcs9_emailAddress, -1)) >= 0) { |
tmpne = X509_NAME_get_entry(dn_subject, i); |
tmpne = X509_NAME_get_entry(dn_subject, i); |
X509_NAME_delete_entry(dn_subject, i); |
if (tmpne == NULL) |
|
goto err; |
|
if (X509_NAME_delete_entry(dn_subject, i) == NULL) { |
|
X509_NAME_ENTRY_free(tmpne); |
|
goto err; |
|
} |
X509_NAME_ENTRY_free(tmpne); |
X509_NAME_ENTRY_free(tmpne); |
} |
} |
} |
} |
|
|
goto err; |
goto err; |
} |
} |
|
|
if (strcmp(startdate, "today") == 0) |
if (strcmp(startdate, "today") == 0) { |
X509_gmtime_adj(X509_get_notBefore(ret), 0); |
if (X509_gmtime_adj(X509_get_notBefore(ret), 0) == NULL) |
else if (setCertificateTime(X509_get_notBefore(ret), startdate) == -1) { |
goto err; |
|
} else if (setCertificateTime(X509_get_notBefore(ret), startdate) == -1) { |
BIO_printf(bio_err, "Invalid start date %s\n", |
BIO_printf(bio_err, "Invalid start date %s\n", |
startdate); |
startdate); |
goto err; |
goto err; |
} |
} |
|
|
if (enddate == NULL) |
if (enddate == NULL) { |
X509_time_adj_ex(X509_get_notAfter(ret), days, 0, NULL); |
if (X509_time_adj_ex(X509_get_notAfter(ret), days, 0, |
else if (setCertificateTime(X509_get_notAfter(ret), enddate) == -1) { |
NULL) == NULL) |
|
goto err; |
|
} else if (setCertificateTime(X509_get_notAfter(ret), enddate) == -1) { |
BIO_printf(bio_err, "Invalid end date %s\n", |
BIO_printf(bio_err, "Invalid end date %s\n", |
enddate); |
enddate); |
goto err; |
goto err; |
|
|
goto err; |
goto err; |
|
|
pktmp = X509_REQ_get_pubkey(req); |
pktmp = X509_REQ_get_pubkey(req); |
|
if (pktmp == NULL) |
|
goto err; |
|
|
i = X509_set_pubkey(ret, pktmp); |
i = X509_set_pubkey(ret, pktmp); |
EVP_PKEY_free(pktmp); |
EVP_PKEY_free(pktmp); |
if (!i) |
if (!i) |
|
|
if (ci->version == NULL) |
if (ci->version == NULL) |
if ((ci->version = ASN1_INTEGER_new()) == NULL) |
if ((ci->version = ASN1_INTEGER_new()) == NULL) |
goto err; |
goto err; |
ASN1_INTEGER_set(ci->version, 2); /* version 3 certificate */ |
|
|
|
|
/* version 3 certificate */ |
|
if (!ASN1_INTEGER_set(ci->version, 2)) |
|
goto err; |
|
|
/* |
/* |
* Free the current entries if any, there should not be any I |
* Free the current entries if any, there should not be any I |
* believe |
* believe |
|
|
* present |
* present |
*/ |
*/ |
certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME; |
certopt |= X509_FLAG_NO_SIGDUMP | X509_FLAG_NO_SIGNAME; |
X509_print_ex(bio_err, ret, nameopt, certopt); |
if (!X509_print_ex(bio_err, ret, nameopt, certopt)) |
|
goto err; |
} |
} |
BIO_printf(bio_err, "Certificate is to be certified until "); |
BIO_printf(bio_err, "Certificate is to be certified until "); |
ASN1_TIME_print(bio_err, X509_get_notAfter(ret)); |
ASN1_TIME_print(bio_err, X509_get_notAfter(ret)); |
|
|
goto err; |
goto err; |
} |
} |
} |
} |
|
|
pktmp = X509_get_pubkey(ret); |
pktmp = X509_get_pubkey(ret); |
|
if (pktmp == NULL) |
|
goto err; |
|
|
if (EVP_PKEY_missing_parameters(pktmp) && |
if (EVP_PKEY_missing_parameters(pktmp) && |
!EVP_PKEY_missing_parameters(pkey)) |
!EVP_PKEY_missing_parameters(pkey)) { |
EVP_PKEY_copy_parameters(pktmp, pkey); |
if (!EVP_PKEY_copy_parameters(pktmp, pkey)) { |
|
EVP_PKEY_free(pktmp); |
|
goto err; |
|
} |
|
} |
EVP_PKEY_free(pktmp); |
EVP_PKEY_free(pktmp); |
|
|
if (!do_X509_sign(bio_err, ret, pkey, dgst, sigopts)) |
if (!do_X509_sign(bio_err, ret, pkey, dgst, sigopts)) |
|
|
return (ok); |
return (ok); |
} |
} |
|
|
static void |
static int |
write_new_certificate(BIO *bp, X509 *x, int output_der, int notext) |
write_new_certificate(BIO *bp, X509 *x, int output_der, int notext) |
{ |
{ |
if (output_der) { |
if (output_der) { |
(void) i2d_X509_bio(bp, x); |
if (!i2d_X509_bio(bp, x)) |
return; |
return (0); |
} |
} |
if (!notext) |
if (!notext) { |
X509_print(bp, x); |
if (!X509_print(bp, x)) |
PEM_write_bio_X509(bp, x); |
return (0); |
|
} |
|
|
|
return PEM_write_bio_X509(bp, x); |
} |
} |
|
|
static int |
static int |
|
|
} |
} |
BIO_printf(bio_err, "Signature ok\n"); |
BIO_printf(bio_err, "Signature ok\n"); |
|
|
X509_REQ_set_pubkey(req, pktmp); |
if (!X509_REQ_set_pubkey(req, pktmp)) { |
|
EVP_PKEY_free(pktmp); |
|
goto err; |
|
} |
EVP_PKEY_free(pktmp); |
EVP_PKEY_free(pktmp); |
ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, |
ok = do_body(xret, pkey, x509, dgst, sigopts, policy, db, serial, |
subj, chtype, multirdn, email_dn, startdate, enddate, days, 1, |
subj, chtype, multirdn, email_dn, startdate, enddate, days, 1, |
|
|
ASN1_UTCTIME *a_tm = NULL; |
ASN1_UTCTIME *a_tm = NULL; |
int i, cnt = 0; |
int i, cnt = 0; |
int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */ |
int db_y2k, a_y2k; /* flags = 1 if y >= 2000 */ |
char **rrow, *a_tm_s; |
char **rrow, *a_tm_s = NULL; |
|
|
a_tm = ASN1_UTCTIME_new(); |
a_tm = ASN1_UTCTIME_new(); |
|
if (a_tm == NULL) { |
|
cnt = -1; |
|
goto err; |
|
} |
|
|
/* get actual time and make a string */ |
/* get actual time and make a string */ |
a_tm = X509_gmtime_adj(a_tm, 0); |
a_tm = X509_gmtime_adj(a_tm, 0); |
|
if (a_tm == NULL) { |
|
cnt = -1; |
|
goto err; |
|
} |
a_tm_s = malloc(a_tm->length + 1); |
a_tm_s = malloc(a_tm->length + 1); |
if (a_tm_s == NULL) { |
if (a_tm_s == NULL) { |
cnt = -1; |
cnt = -1; |
|
|
|
|
case REV_HOLD: |
case REV_HOLD: |
/* Argument is an OID */ |
/* Argument is an OID */ |
|
|
otmp = OBJ_txt2obj(rev_arg, 0); |
otmp = OBJ_txt2obj(rev_arg, 0); |
ASN1_OBJECT_free(otmp); |
ASN1_OBJECT_free(otmp); |
|
|
|
|
|
|
case REV_KEY_COMPROMISE: |
case REV_KEY_COMPROMISE: |
case REV_CA_COMPROMISE: |
case REV_CA_COMPROMISE: |
|
|
/* Argument is the key compromise time */ |
/* Argument is the key compromise time */ |
if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) { |
if (!ASN1_GENERALIZEDTIME_set_string(NULL, rev_arg)) { |
BIO_printf(bio_err, |
BIO_printf(bio_err, |
|
|
reason = "CAkeyTime"; |
reason = "CAkeyTime"; |
|
|
break; |
break; |
|
|
} |
} |
|
|
revtm = X509_gmtime_adj(NULL, 0); |
revtm = X509_gmtime_adj(NULL, 0); |
|
if (revtm == NULL) |
|
return NULL; |
|
|
if (asprintf(&str, "%s%s%s%s%s", revtm->data, |
if (asprintf(&str, "%s%s%s%s%s", revtm->data, |
reason ? "," : "", reason ? reason : "", |
reason ? "," : "", reason ? reason : "", |
other ? "," : "", other ? other : "") == -1) |
other ? "," : "", other ? other : "") == -1) |
str = NULL; |
str = NULL; |
|
|
ASN1_UTCTIME_free(revtm); |
ASN1_UTCTIME_free(revtm); |
|
|
return str; |
return str; |
} |
} |
|
|