📄 ca.c
字号:
*/ hx509_set_error_string(context, 0, EINVAL, "CRLDistributionPoints.name.issuername not yet supported"); return EINVAL;#else GeneralNames *crlissuer; GeneralName gn; Name n; crlissuer = calloc(1, sizeof(*crlissuer)); if (crlissuer == NULL) { return ENOMEM; } memset(&gn, 0, sizeof(gn)); gn.element = choice_GeneralName_directoryName; ret = hx509_name_to_Name(issuername, &n); if (ret) { hx509_set_error_string(context, 0, ret, "out of memory"); goto out; } gn.u.directoryName.element = n.element; gn.u.directoryName.u.rdnSequence = n.u.rdnSequence; ret = add_GeneralNames(&crlissuer, &gn); free_Name(&n); if (ret) { hx509_set_error_string(context, 0, ret, "out of memory"); goto out; } dp.cRLIssuer = &crlissuer;#endif } ret = add_CRLDistributionPoints(&tbs->crldp, &dp); if (ret) { hx509_set_error_string(context, 0, ret, "out of memory"); goto out; }out: free_DistributionPoint(&dp); return ret;}/** * Add Subject Alternative Name otherName to the to-be-signed * certificate object. * * @param context A hx509 context. * @param tbs object to be signed. * @param oid the oid of the OtherName. * @param os data in the other name. * * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_ca */inthx509_ca_tbs_add_san_otherName(hx509_context context, hx509_ca_tbs tbs, const heim_oid *oid, const heim_octet_string *os){ GeneralName gn; memset(&gn, 0, sizeof(gn)); gn.element = choice_GeneralName_otherName; gn.u.otherName.type_id = *oid; gn.u.otherName.value = *os; return add_GeneralNames(&tbs->san, &gn);}/** * Add Kerberos Subject Alternative Name to the to-be-signed * certificate object. The principal string is a UTF8 string. * * @param context A hx509 context. * @param tbs object to be signed. * @param principal Kerberos principal to add to the certificate. * * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_ca */inthx509_ca_tbs_add_san_pkinit(hx509_context context, hx509_ca_tbs tbs, const char *principal){ heim_octet_string os; KRB5PrincipalName p; size_t size; int ret; char *s = NULL; memset(&p, 0, sizeof(p)); /* parse principal */ { const char *str; char *q; int n; /* count number of component */ n = 1; for(str = principal; *str != '\0' && *str != '@'; str++){ if(*str=='\\'){ if(str[1] == '\0' || str[1] == '@') { ret = HX509_PARSING_NAME_FAILED; hx509_set_error_string(context, 0, ret, "trailing \\ in principal name"); goto out; } str++; } else if(*str == '/') n++; } p.principalName.name_string.val = calloc(n, sizeof(*p.principalName.name_string.val)); if (p.principalName.name_string.val == NULL) { ret = ENOMEM; hx509_set_error_string(context, 0, ret, "malloc: out of memory"); goto out; } p.principalName.name_string.len = n; p.principalName.name_type = KRB5_NT_PRINCIPAL; q = s = strdup(principal); if (q == NULL) { ret = ENOMEM; hx509_set_error_string(context, 0, ret, "malloc: out of memory"); goto out; } p.realm = strrchr(q, '@'); if (p.realm == NULL) { ret = HX509_PARSING_NAME_FAILED; hx509_set_error_string(context, 0, ret, "Missing @ in principal"); goto out; }; *p.realm++ = '\0'; n = 0; while (q) { p.principalName.name_string.val[n++] = q; q = strchr(q, '/'); if (q) *q++ = '\0'; } } ASN1_MALLOC_ENCODE(KRB5PrincipalName, os.data, os.length, &p, &size, ret); if (ret) { hx509_set_error_string(context, 0, ret, "Out of memory"); goto out; } if (size != os.length) _hx509_abort("internal ASN.1 encoder error"); ret = hx509_ca_tbs_add_san_otherName(context, tbs, oid_id_pkinit_san(), &os); free(os.data);out: if (p.principalName.name_string.val) free (p.principalName.name_string.val); if (s) free(s); return ret;} /* * */static intadd_utf8_san(hx509_context context, hx509_ca_tbs tbs, const heim_oid *oid, const char *string){ const PKIXXmppAddr ustring = (const PKIXXmppAddr)string; heim_octet_string os; size_t size; int ret; os.length = 0; os.data = NULL; ASN1_MALLOC_ENCODE(PKIXXmppAddr, os.data, os.length, &ustring, &size, ret); if (ret) { hx509_set_error_string(context, 0, ret, "Out of memory"); goto out; } if (size != os.length) _hx509_abort("internal ASN.1 encoder error"); ret = hx509_ca_tbs_add_san_otherName(context, tbs, oid, &os); free(os.data);out: return ret;}/** * Add Microsoft UPN Subject Alternative Name to the to-be-signed * certificate object. The principal string is a UTF8 string. * * @param context A hx509 context. * @param tbs object to be signed. * @param principal Microsoft UPN string. * * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_ca */inthx509_ca_tbs_add_san_ms_upn(hx509_context context, hx509_ca_tbs tbs, const char *principal){ return add_utf8_san(context, tbs, oid_id_pkinit_ms_san(), principal);}/** * Add a Jabber/XMPP jid Subject Alternative Name to the to-be-signed * certificate object. The jid is an UTF8 string. * * @param context A hx509 context. * @param tbs object to be signed. * @param jid string of an a jabber id in UTF8. * * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_ca */inthx509_ca_tbs_add_san_jid(hx509_context context, hx509_ca_tbs tbs, const char *jid){ return add_utf8_san(context, tbs, oid_id_pkix_on_xmppAddr(), jid);}/** * Add a Subject Alternative Name hostname to to-be-signed certificate * object. A domain match starts with ., an exact match does not. * * Example of a an domain match: .domain.se matches the hostname * host.domain.se. * * @param context A hx509 context. * @param tbs object to be signed. * @param dnsname a hostame. * * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_ca */inthx509_ca_tbs_add_san_hostname(hx509_context context, hx509_ca_tbs tbs, const char *dnsname){ GeneralName gn; memset(&gn, 0, sizeof(gn)); gn.element = choice_GeneralName_dNSName; gn.u.dNSName = rk_UNCONST(dnsname); return add_GeneralNames(&tbs->san, &gn);}/** * Add a Subject Alternative Name rfc822 (email address) to * to-be-signed certificate object. * * @param context A hx509 context. * @param tbs object to be signed. * @param rfc822Name a string to a email address. * * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_ca */inthx509_ca_tbs_add_san_rfc822name(hx509_context context, hx509_ca_tbs tbs, const char *rfc822Name){ GeneralName gn; memset(&gn, 0, sizeof(gn)); gn.element = choice_GeneralName_rfc822Name; gn.u.rfc822Name = rk_UNCONST(rfc822Name); return add_GeneralNames(&tbs->san, &gn);}/** * Set the subject name of a to-be-signed certificate object. * * @param context A hx509 context. * @param tbs object to be signed. * @param subject the name to set a subject. * * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_ca */inthx509_ca_tbs_set_subject(hx509_context context, hx509_ca_tbs tbs, hx509_name subject){ if (tbs->subject) hx509_name_free(&tbs->subject); return hx509_name_copy(context, subject, &tbs->subject);}/** * Expand the the subject name in the to-be-signed certificate object * using hx509_name_expand(). * * @param context A hx509 context. * @param tbs object to be signed. * @param env enviroment variable to expand variables in the subject * name, see hx509_env_init(). * * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_ca */inthx509_ca_tbs_subject_expand(hx509_context context, hx509_ca_tbs tbs, hx509_env env){ return hx509_name_expand(context, tbs->subject, env);}static intadd_extension(hx509_context context, TBSCertificate *tbsc, int critical_flag, const heim_oid *oid, const heim_octet_string *data){ Extension ext; int ret; memset(&ext, 0, sizeof(ext)); if (critical_flag) { ext.critical = malloc(sizeof(*ext.critical)); if (ext.critical == NULL) { ret = ENOMEM; hx509_set_error_string(context, 0, ret, "Out of memory"); goto out; } *ext.critical = TRUE; } ret = der_copy_oid(oid, &ext.extnID); if (ret) { hx509_set_error_string(context, 0, ret, "Out of memory"); goto out; } ret = der_copy_octet_string(data, &ext.extnValue); if (ret) { hx509_set_error_string(context, 0, ret, "Out of memory"); goto out; } ret = add_Extensions(tbsc->extensions, &ext); if (ret) { hx509_set_error_string(context, 0, ret, "Out of memory"); goto out; }out: free_Extension(&ext); return ret;}static intbuild_proxy_prefix(hx509_context context, const Name *issuer, Name *subject){ char *tstr; time_t t; int ret; ret = copy_Name(issuer, subject); if (ret) { hx509_set_error_string(context, 0, ret, "Failed to copy subject name"); return ret; } t = time(NULL); asprintf(&tstr, "ts-%lu", (unsigned long)t); if (tstr == NULL) { hx509_set_error_string(context, 0, ENOMEM, "Failed to copy subject name"); return ENOMEM; } /* prefix with CN=<ts>,...*/ ret = _hx509_name_modify(context, subject, 1, oid_id_at_commonName(), tstr); free(tstr); if (ret) free_Name(subject); return ret;}static intca_sign(hx509_context context, hx509_ca_tbs tbs, hx509_private_key signer, const AuthorityKeyIdentifier *ai, const Name *issuername, hx509_cert *certificate){ heim_octet_string data; Certificate c; TBSCertificate *tbsc; size_t size; int ret; const AlgorithmIdentifier *sigalg; time_t notBefore; time_t notAfter; unsigned key_usage; sigalg = _hx509_crypto_default_sig_alg; memset(&c, 0, sizeof(c)); /* * Default values are: Valid since 24h ago, valid one year into * the future, KeyUsage digitalSignature and keyEncipherment set, * and keyCertSign for CA certificates. */ notBefore = tbs->notBefore; if (notBefore == 0) notBefore = time(NULL) - 3600 * 24; notAfter = tbs->notAfter; if (notAfter == 0) notAfter = time(NULL) + 3600 * 24 * 365; key_usage = tbs->key_usage; if (key_usage == 0) { KeyUsage ku; memset(&ku, 0, sizeof(ku)); ku.digitalSignature = 1; ku.keyEncipherment = 1; key_usage = KeyUsage2int(ku); } if (tbs->flags.ca) { KeyUsage ku; memset(&ku, 0, sizeof(ku)); ku.keyCertSign = 1; ku.cRLSign = 1; key_usage |= KeyUsage2int(ku); } /* * */ tbsc = &c.tbsCertificate; if (tbs->flags.key == 0) { ret = EINVAL; hx509_set_error_string(context, 0, ret, "No public key set"); return ret; } /* * Don't put restrictions on proxy certificate's subject name, it * will be generated below. */ if (!tbs->flags.proxy) { if (tbs->subject == NULL) { hx509_set_error_string(context, 0, EINVAL, "No subject name set"); return EINVAL; } if (hx509_name_is_null_p(tbs->subject) && tbs->san.len == 0) { hx509_set_error_string(context, 0, EINVAL, "NULL subject and no SubjectAltNames"); return EINVAL; } } if (tbs->flags.ca && tbs->flags.proxy) { hx509_set_error_string(context, 0, EINVAL, "Can't be proxy and CA "
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -