static int verify_callback(int ok, X509_STORE_CTX *ctx) { char *userid; X509 *xs; PROXY_CERT_INFO_EXTENSION *pci; char *credstr; PVFS_credentials *credentials; char error_msg[256]; int ret; /* prior verifies have succeeded */ if (ok == 1) { /* parse the credential string uid/gid from the policy */ xs = ctx->current_cert; if (xs->ex_flags & EXFLAG_PROXY) { /* get userid for error logging */ userid = (char *) X509_STORE_CTX_get_ex_data(ctx, get_proxy_auth_ex_data_userid()); /* get credentials in {UID}/{GID} form from cert policy */ pci = (PROXY_CERT_INFO_EXTENSION *) X509_get_ext_d2i(xs, NID_proxyCertInfo, NULL, NULL); if (pci->proxyPolicy->policy != NULL && pci->proxyPolicy->policy->length > 0) { credstr = (char *) pci->proxyPolicy->policy->data; credentials = (PVFS_credentials *) X509_STORE_CTX_get_ex_data( ctx, get_proxy_auth_ex_data_cred()); ret = parse_credentials(credstr, &credentials->uid, &credentials->gid); if (ret != 0) { _snprintf(error_msg, sizeof(error_msg), "User %s: proxy " "certificate contains invalid credential policy", userid); report_cert_error(error_msg); ok = 0; } } else { _snprintf(error_msg, sizeof(error_msg), "User %s: proxy " "certificate contains no credential policy", userid); report_cert_error(error_msg); ok = 0; } PROXY_CERT_INFO_EXTENSION_free(pci); } } return ok; }
static void x509v3_cache_extensions(X509 *x) { BASIC_CONSTRAINTS *bs; PROXY_CERT_INFO_EXTENSION *pci; ASN1_BIT_STRING *usage; ASN1_BIT_STRING *ns; EXTENDED_KEY_USAGE *extusage; X509_EXTENSION *ex; int i; if(x->ex_flags & EXFLAG_SET) return; #ifndef OPENSSL_NO_SHA X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); #endif /* Does subject name match issuer ? */ if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) x->ex_flags |= EXFLAG_SS; /* V1 should mean no extensions ... */ if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1; /* Handle basic constraints */ if((bs=X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) { if(bs->ca) x->ex_flags |= EXFLAG_CA; if(bs->pathlen) { if((bs->pathlen->type == V_ASN1_NEG_INTEGER) || !bs->ca) { x->ex_flags |= EXFLAG_INVALID; x->ex_pathlen = 0; } else x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); } else x->ex_pathlen = -1; BASIC_CONSTRAINTS_free(bs); x->ex_flags |= EXFLAG_BCONS; } /* Handle proxy certificates */ if((pci=X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) { if (x->ex_flags & EXFLAG_CA || X509_get_ext_by_NID(x, NID_subject_alt_name, 0) >= 0 || X509_get_ext_by_NID(x, NID_issuer_alt_name, 0) >= 0) { x->ex_flags |= EXFLAG_INVALID; } if (pci->pcPathLengthConstraint) { x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint); } else x->ex_pcpathlen = -1; PROXY_CERT_INFO_EXTENSION_free(pci); x->ex_flags |= EXFLAG_PROXY; } /* Handle key usage */ if((usage=X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { if(usage->length > 0) { x->ex_kusage = usage->data[0]; if(usage->length > 1) x->ex_kusage |= usage->data[1] << 8; } else x->ex_kusage = 0; x->ex_flags |= EXFLAG_KUSAGE; ASN1_BIT_STRING_free(usage); } x->ex_xkusage = 0; if((extusage=X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) { x->ex_flags |= EXFLAG_XKUSAGE; for(i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { switch(OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage,i))) { case NID_server_auth: x->ex_xkusage |= XKU_SSL_SERVER; break; case NID_client_auth: x->ex_xkusage |= XKU_SSL_CLIENT; break; case NID_email_protect: x->ex_xkusage |= XKU_SMIME; break; case NID_code_sign: x->ex_xkusage |= XKU_CODE_SIGN; break; case NID_ms_sgc: case NID_ns_sgc: x->ex_xkusage |= XKU_SGC; break; case NID_OCSP_sign: x->ex_xkusage |= XKU_OCSP_SIGN; break; case NID_time_stamp: x->ex_xkusage |= XKU_TIMESTAMP; break; case NID_dvcs: x->ex_xkusage |= XKU_DVCS; break; } } sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); } if((ns=X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) { if(ns->length > 0) x->ex_nscert = ns->data[0]; else x->ex_nscert = 0; x->ex_flags |= EXFLAG_NSCERT; ASN1_BIT_STRING_free(ns); } x->skid =X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); x->akid =X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); for (i = 0; i < X509_get_ext_count(x); i++) { ex = X509_get_ext(x, i); if (!X509_EXTENSION_get_critical(ex)) continue; if (!X509_supported_extension(ex)) { x->ex_flags |= EXFLAG_CRITICAL; break; } } x->ex_flags |= EXFLAG_SET; }
static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value) { PROXY_CERT_INFO_EXTENSION *pci = NULL; STACK_OF(CONF_VALUE) *vals; ASN1_OBJECT *language = NULL; ASN1_INTEGER *pathlen = NULL; ASN1_OCTET_STRING *policy = NULL; int i, j; vals = X509V3_parse_list(value); for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i); if (!cnf->name || (*cnf->name != '@' && !cnf->value)) { X509V3err(X509V3_F_R2I_PCI, X509V3_R_INVALID_PROXY_POLICY_SETTING); X509V3_conf_err(cnf); goto err; } if (*cnf->name == '@') { STACK_OF(CONF_VALUE) *sect; int success_p = 1; sect = X509V3_get_section(ctx, cnf->name + 1); if (!sect) { X509V3err(X509V3_F_R2I_PCI, X509V3_R_INVALID_SECTION); X509V3_conf_err(cnf); goto err; } for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) { success_p = process_pci_value(sk_CONF_VALUE_value(sect, j), &language, &pathlen, &policy); } X509V3_section_free(ctx, sect); if (!success_p) goto err; } else { if (!process_pci_value(cnf, &language, &pathlen, &policy)) { X509V3_conf_err(cnf); goto err; } } } /* Language is mandatory */ if (!language) { X509V3err(X509V3_F_R2I_PCI, X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); goto err; } i = OBJ_obj2nid(language); if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) { X509V3err(X509V3_F_R2I_PCI, X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); goto err; } pci = PROXY_CERT_INFO_EXTENSION_new(); if (pci == NULL) { X509V3err(X509V3_F_R2I_PCI, ERR_R_MALLOC_FAILURE); goto err; } pci->proxyPolicy->policyLanguage = language; language = NULL; pci->proxyPolicy->policy = policy; policy = NULL; pci->pcPathLengthConstraint = pathlen; pathlen = NULL; goto end; err: ASN1_OBJECT_free(language); ASN1_INTEGER_free(pathlen); pathlen = NULL; ASN1_OCTET_STRING_free(policy); policy = NULL; PROXY_CERT_INFO_EXTENSION_free(pci); pci = NULL; end: sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); return pci; }