int mono_btls_x509_verify_param_set_depth (MonoBtlsX509VerifyParam *param, int depth) { if (!param->owns) return -1; X509_VERIFY_PARAM_set_depth (param->param, depth); return 1; }
int opt_verify(int opt, X509_VERIFY_PARAM *vpm) { int i; ossl_intmax_t t = 0; ASN1_OBJECT *otmp; X509_PURPOSE *xptmp; const X509_VERIFY_PARAM *vtmp; assert(vpm != NULL); assert(opt > OPT_V__FIRST); assert(opt < OPT_V__LAST); switch ((enum range)opt) { case OPT_V__FIRST: case OPT_V__LAST: return 0; case OPT_V_POLICY: otmp = OBJ_txt2obj(opt_arg(), 0); if (otmp == NULL) { BIO_printf(bio_err, "%s: Invalid Policy %s\n", prog, opt_arg()); return 0; } X509_VERIFY_PARAM_add0_policy(vpm, otmp); break; case OPT_V_PURPOSE: /* purpose name -> purpose index */ i = X509_PURPOSE_get_by_sname(opt_arg()); if (i < 0) { BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg()); return 0; } /* purpose index -> purpose object */ xptmp = X509_PURPOSE_get0(i); /* purpose object -> purpose value */ i = X509_PURPOSE_get_id(xptmp); if (!X509_VERIFY_PARAM_set_purpose(vpm, i)) { BIO_printf(bio_err, "%s: Internal error setting purpose %s\n", prog, opt_arg()); return 0; } break; case OPT_V_VERIFY_NAME: vtmp = X509_VERIFY_PARAM_lookup(opt_arg()); if (vtmp == NULL) { BIO_printf(bio_err, "%s: Invalid verify name %s\n", prog, opt_arg()); return 0; } X509_VERIFY_PARAM_set1(vpm, vtmp); break; case OPT_V_VERIFY_DEPTH: i = atoi(opt_arg()); if (i >= 0) X509_VERIFY_PARAM_set_depth(vpm, i); break; case OPT_V_VERIFY_AUTH_LEVEL: i = atoi(opt_arg()); if (i >= 0) X509_VERIFY_PARAM_set_auth_level(vpm, i); break; case OPT_V_ATTIME: if (!opt_imax(opt_arg(), &t)) return 0; if (t != (time_t)t) { BIO_printf(bio_err, "%s: epoch time out of range %s\n", prog, opt_arg()); return 0; } X509_VERIFY_PARAM_set_time(vpm, (time_t)t); break; case OPT_V_VERIFY_HOSTNAME: if (!X509_VERIFY_PARAM_set1_host(vpm, opt_arg(), 0)) return 0; break; case OPT_V_VERIFY_EMAIL: if (!X509_VERIFY_PARAM_set1_email(vpm, opt_arg(), 0)) return 0; break; case OPT_V_VERIFY_IP: if (!X509_VERIFY_PARAM_set1_ip_asc(vpm, opt_arg())) return 0; break; case OPT_V_IGNORE_CRITICAL: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_IGNORE_CRITICAL); break; case OPT_V_ISSUER_CHECKS: /* NOP, deprecated */ break; case OPT_V_CRL_CHECK: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK); break; case OPT_V_CRL_CHECK_ALL: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); break; case OPT_V_POLICY_CHECK: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_POLICY_CHECK); break; case OPT_V_EXPLICIT_POLICY: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXPLICIT_POLICY); break; case OPT_V_INHIBIT_ANY: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_ANY); break; case OPT_V_INHIBIT_MAP: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_MAP); break; case OPT_V_X509_STRICT: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_X509_STRICT); break; case OPT_V_EXTENDED_CRL: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXTENDED_CRL_SUPPORT); break; case OPT_V_USE_DELTAS: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_USE_DELTAS); break; case OPT_V_POLICY_PRINT: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NOTIFY_POLICY); break; case OPT_V_CHECK_SS_SIG: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CHECK_SS_SIGNATURE); break; case OPT_V_TRUSTED_FIRST: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_TRUSTED_FIRST); break; case OPT_V_SUITEB_128_ONLY: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS_ONLY); break; case OPT_V_SUITEB_128: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS); break; case OPT_V_SUITEB_192: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_192_LOS); break; case OPT_V_PARTIAL_CHAIN: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_PARTIAL_CHAIN); break; case OPT_V_NO_ALT_CHAINS: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_ALT_CHAINS); break; case OPT_V_NO_CHECK_TIME: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_CHECK_TIME); break; } return 1; }
static int xmlSecOpenSSLX509StoreInitialize(xmlSecKeyDataStorePtr store) { const xmlChar* path; X509_LOOKUP *lookup = NULL; xmlSecOpenSSLX509StoreCtxPtr ctx; xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecOpenSSLX509StoreId), -1); ctx = xmlSecOpenSSLX509StoreGetCtx(store); xmlSecAssert2(ctx != NULL, -1); memset(ctx, 0, sizeof(xmlSecOpenSSLX509StoreCtx)); ctx->xst = X509_STORE_new(); if(ctx->xst == NULL) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "X509_STORE_new"); return(-1); } if(!X509_STORE_set_default_paths(ctx->xst)) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "X509_STORE_set_default_paths"); return(-1); } lookup = X509_STORE_add_lookup(ctx->xst, X509_LOOKUP_hash_dir()); if(lookup == NULL) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "X509_STORE_add_lookup"); return(-1); } path = xmlSecOpenSSLGetDefaultTrustedCertsFolder(); if(path != NULL) { if(!X509_LOOKUP_add_dir(lookup, (char*)path, X509_FILETYPE_PEM)) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "X509_LOOKUP_add_dir"); return(-1); } } else { if(!X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT)) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "X509_LOOKUP_add_dir"); return(-1); } } ctx->untrusted = sk_X509_new_null(); if(ctx->untrusted == NULL) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "sk_X509_new_null"); return(-1); } ctx->crls = sk_X509_CRL_new_null(); if(ctx->crls == NULL) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "sk_X509_CRL_new_null"); return(-1); } ctx->vpm = X509_VERIFY_PARAM_new(); if(ctx->vpm == NULL) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "X509_VERIFY_PARAM_new"); return(-1); } X509_VERIFY_PARAM_set_depth(ctx->vpm, 9); /* the default cert verification path in openssl */ X509_STORE_set1_param(ctx->xst, ctx->vpm); return(0); }
int opt_verify(int opt, X509_VERIFY_PARAM *vpm) { unsigned long ul; int i; ASN1_OBJECT *otmp; X509_PURPOSE *xptmp; const X509_VERIFY_PARAM *vtmp; assert(vpm != NULL); assert(opt > OPT_V__FIRST); assert(opt < OPT_V__LAST); switch ((enum range)opt) { case OPT_V__FIRST: case OPT_V__LAST: return 0; case OPT_V_POLICY: otmp = OBJ_txt2obj(opt_arg(), 0); if (otmp == NULL) { BIO_printf(bio_err, "%s: Invalid Policy %s\n", prog, opt_arg()); return 0; } X509_VERIFY_PARAM_add0_policy(vpm, otmp); break; case OPT_V_PURPOSE: i = X509_PURPOSE_get_by_sname(opt_arg()); if (i < 0) { BIO_printf(bio_err, "%s: Invalid purpose %s\n", prog, opt_arg()); return 0; } xptmp = X509_PURPOSE_get0(i); i = X509_PURPOSE_get_id(xptmp); X509_VERIFY_PARAM_set_purpose(vpm, i); break; case OPT_V_VERIFY_NAME: vtmp = X509_VERIFY_PARAM_lookup(opt_arg()); if (vtmp == NULL) { BIO_printf(bio_err, "%s: Invalid verify name %s\n", prog, opt_arg()); return 0; } X509_VERIFY_PARAM_set1(vpm, vtmp); break; case OPT_V_VERIFY_DEPTH: i = atoi(opt_arg()); if (i >= 0) X509_VERIFY_PARAM_set_depth(vpm, i); break; case OPT_V_ATTIME: opt_ulong(opt_arg(), &ul); if (ul) X509_VERIFY_PARAM_set_time(vpm, (time_t)ul); break; case OPT_V_VERIFY_HOSTNAME: if (!X509_VERIFY_PARAM_set1_host(vpm, opt_arg(), 0)) return 0; break; case OPT_V_VERIFY_EMAIL: if (!X509_VERIFY_PARAM_set1_email(vpm, opt_arg(), 0)) return 0; break; case OPT_V_VERIFY_IP: if (!X509_VERIFY_PARAM_set1_ip_asc(vpm, opt_arg())) return 0; break; case OPT_V_IGNORE_CRITICAL: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_IGNORE_CRITICAL); break; case OPT_V_ISSUER_CHECKS: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CB_ISSUER_CHECK); break; case OPT_V_CRL_CHECK: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK); break; case OPT_V_CRL_CHECK_ALL: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); break; case OPT_V_POLICY_CHECK: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_POLICY_CHECK); break; case OPT_V_EXPLICIT_POLICY: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXPLICIT_POLICY); break; case OPT_V_INHIBIT_ANY: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_ANY); break; case OPT_V_INHIBIT_MAP: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_INHIBIT_MAP); break; case OPT_V_X509_STRICT: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_X509_STRICT); break; case OPT_V_EXTENDED_CRL: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_EXTENDED_CRL_SUPPORT); break; case OPT_V_USE_DELTAS: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_USE_DELTAS); break; case OPT_V_POLICY_PRINT: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NOTIFY_POLICY); break; case OPT_V_CHECK_SS_SIG: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_CHECK_SS_SIGNATURE); break; case OPT_V_TRUSTED_FIRST: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_TRUSTED_FIRST); break; case OPT_V_SUITEB_128_ONLY: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS_ONLY); break; case OPT_V_SUITEB_128: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_128_LOS); break; case OPT_V_SUITEB_192: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_SUITEB_192_LOS); break; case OPT_V_PARTIAL_CHAIN: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_PARTIAL_CHAIN); break; case OPT_V_NO_ALT_CHAINS: X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_NO_ALT_CHAINS); } return 1; }
/** * xmlSecOpenSSLX509StoreVerify: * @store: the pointer to X509 key data store klass. * @certs: the untrusted certificates stack. * @crls: the crls stack. * @keyInfoCtx: the pointer to <dsig:KeyInfo/> element processing context. * * Verifies @certs list. * * Returns: pointer to the first verified certificate from @certs. */ X509* xmlSecOpenSSLX509StoreVerify(xmlSecKeyDataStorePtr store, XMLSEC_STACK_OF_X509* certs, XMLSEC_STACK_OF_X509_CRL* crls, xmlSecKeyInfoCtx* keyInfoCtx) { xmlSecOpenSSLX509StoreCtxPtr ctx; STACK_OF(X509)* certs2 = NULL; STACK_OF(X509_CRL)* crls2 = NULL; X509 * res = NULL; X509 * cert; X509 * err_cert = NULL; X509_STORE_CTX *xsc; char buf[256]; int err = 0; int i; int ret; xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecOpenSSLX509StoreId), NULL); xmlSecAssert2(certs != NULL, NULL); xmlSecAssert2(keyInfoCtx != NULL, NULL); xsc = X509_STORE_CTX_new(); if(xsc == NULL) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "X509_STORE_CTX_new"); goto done; } ctx = xmlSecOpenSSLX509StoreGetCtx(store); xmlSecAssert2(ctx != NULL, NULL); xmlSecAssert2(ctx->xst != NULL, NULL); /* dup certs */ certs2 = sk_X509_dup(certs); if(certs2 == NULL) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "sk_X509_dup"); goto done; } /* add untrusted certs from the store */ if(ctx->untrusted != NULL) { for(i = 0; i < sk_X509_num(ctx->untrusted); ++i) { ret = sk_X509_push(certs2, sk_X509_value(ctx->untrusted, i)); if(ret < 1) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "sk_X509_push"); goto done; } } } /* dup crls but remove all non-verified */ if(crls != NULL) { crls2 = sk_X509_CRL_dup(crls); if(crls2 == NULL) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "sk_X509_CRL_dup"); goto done; } for(i = 0; i < sk_X509_CRL_num(crls2); ) { ret = xmlSecOpenSSLX509VerifyCRL(ctx->xst, sk_X509_CRL_value(crls2, i)); if(ret == 1) { ++i; } else if(ret == 0) { (void)sk_X509_CRL_delete(crls2, i); } else { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "xmlSecOpenSSLX509VerifyCRL", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); goto done; } } } /* remove all revoked certs */ for(i = 0; i < sk_X509_num(certs2);) { cert = sk_X509_value(certs2, i); if(crls2 != NULL) { ret = xmlSecOpenSSLX509VerifyCertAgainstCrls(crls2, cert); if(ret == 0) { (void)sk_X509_delete(certs2, i); continue; } else if(ret != 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "xmlSecOpenSSLX509VerifyCertAgainstCrls", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); goto done; } } if(ctx->crls != NULL) { ret = xmlSecOpenSSLX509VerifyCertAgainstCrls(ctx->crls, cert); if(ret == 0) { (void)sk_X509_delete(certs2, i); continue; } else if(ret != 1) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "xmlSecOpenSSLX509VerifyCertAgainstCrls", XMLSEC_ERRORS_R_XMLSEC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); goto done; } } ++i; } /* get one cert after another and try to verify */ for(i = 0; i < sk_X509_num(certs2); ++i) { cert = sk_X509_value(certs2, i); if(xmlSecOpenSSLX509FindNextChainCert(certs2, cert) == NULL) { ret = X509_STORE_CTX_init(xsc, ctx->xst, cert, certs2); if(ret != 1) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "X509_STORE_CTX_init"); goto done; } if(keyInfoCtx->certsVerificationTime > 0) { X509_STORE_CTX_set_time(xsc, 0, keyInfoCtx->certsVerificationTime); } { X509_VERIFY_PARAM * vpm = NULL; unsigned long vpm_flags = 0; vpm = X509_VERIFY_PARAM_new(); if(vpm == NULL) { xmlSecOpenSSLError(xmlSecKeyDataStoreGetName(store), "X509_VERIFY_PARAM_new"); goto done; } vpm_flags = X509_VERIFY_PARAM_get_flags(vpm); vpm_flags &= (~X509_V_FLAG_CRL_CHECK); if(keyInfoCtx->certsVerificationTime > 0) { vpm_flags |= X509_V_FLAG_USE_CHECK_TIME; X509_VERIFY_PARAM_set_time(vpm, keyInfoCtx->certsVerificationTime); } X509_VERIFY_PARAM_set_depth(vpm, keyInfoCtx->certsVerificationDepth); X509_VERIFY_PARAM_set_flags(vpm, vpm_flags); X509_STORE_CTX_set0_param(xsc, vpm); } ret = X509_verify_cert(xsc); err_cert = X509_STORE_CTX_get_current_cert(xsc); err = X509_STORE_CTX_get_error(xsc); X509_STORE_CTX_cleanup (xsc); if(ret == 1) { res = cert; goto done; } else if(ret < 0) { const char* err_msg; buf[0] = '\0'; X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof buf); err_msg = X509_verify_cert_error_string(err); xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "X509_verify_cert", XMLSEC_ERRORS_R_CRYPTO_FAILED, "subj=%s;err=%d;msg=%s", xmlSecErrorsSafeString(buf), err, xmlSecErrorsSafeString(err_msg)); goto done; } else if(ret == 0) { const char* err_msg; buf[0] = '\0'; X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof buf); err_msg = X509_verify_cert_error_string(err); xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "X509_verify_cert", XMLSEC_ERRORS_R_CRYPTO_FAILED, "subj=%s;err=%d;msg=%s", xmlSecErrorsSafeString(buf), err, xmlSecErrorsSafeString(err_msg)); } } } /* if we came here then we found nothing. do we have any error? */ if((err != 0) && (err_cert != NULL)) { const char* err_msg; err_msg = X509_verify_cert_error_string(err); switch (err) { case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: X509_NAME_oneline(X509_get_issuer_name(err_cert), buf, sizeof buf); xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), NULL, XMLSEC_ERRORS_R_CERT_ISSUER_FAILED, "err=%d;msg=%s;issuer=%s", err, xmlSecErrorsSafeString(err_msg), xmlSecErrorsSafeString(buf)); break; case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), NULL, XMLSEC_ERRORS_R_CERT_NOT_YET_VALID, "err=%d;msg=%s", err, xmlSecErrorsSafeString(err_msg)); break; case X509_V_ERR_CERT_HAS_EXPIRED: case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), NULL, XMLSEC_ERRORS_R_CERT_HAS_EXPIRED, "err=%d;msg=%s", err, xmlSecErrorsSafeString(err_msg)); break; default: xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), NULL, XMLSEC_ERRORS_R_CERT_VERIFY_FAILED, "err=%d;msg=%s", err, xmlSecErrorsSafeString(err_msg)); } } done: if(certs2 != NULL) { sk_X509_free(certs2); } if(crls2 != NULL) { sk_X509_CRL_free(crls2); } if(xsc != NULL) { X509_STORE_CTX_free(xsc); } return(res); }
s2n_cert_validation_code s2n_x509_validator_validate_cert_chain(struct s2n_x509_validator *validator, struct s2n_connection *conn, uint8_t *cert_chain_in, uint32_t cert_chain_len, s2n_cert_type *cert_type, struct s2n_pkey *public_key_out) { if (!validator->skip_cert_validation && !s2n_x509_trust_store_has_certs(validator->trust_store)) { return S2N_CERT_ERR_UNTRUSTED; } DEFER_CLEANUP(X509_STORE_CTX *ctx = NULL, X509_STORE_CTX_free_pointer); struct s2n_blob cert_chain_blob = {.data = cert_chain_in, .size = cert_chain_len}; DEFER_CLEANUP(struct s2n_stuffer cert_chain_in_stuffer = {{0}}, s2n_stuffer_free); if (s2n_stuffer_init(&cert_chain_in_stuffer, &cert_chain_blob) < 0) { return S2N_CERT_ERR_INVALID; } if (s2n_stuffer_write(&cert_chain_in_stuffer, &cert_chain_blob) < 0) { return S2N_CERT_ERR_INVALID; } uint32_t certificate_count = 0; X509 *server_cert = NULL; DEFER_CLEANUP(struct s2n_pkey public_key = {{{0}}}, s2n_pkey_free); s2n_pkey_zero_init(&public_key); while (s2n_stuffer_data_available(&cert_chain_in_stuffer) && certificate_count < validator->max_chain_depth) { uint32_t certificate_size = 0; if (s2n_stuffer_read_uint24(&cert_chain_in_stuffer, &certificate_size) < 0) { return S2N_CERT_ERR_INVALID; } if (certificate_size == 0 || certificate_size > s2n_stuffer_data_available(&cert_chain_in_stuffer)) { return S2N_CERT_ERR_INVALID; } struct s2n_blob asn1cert = {0}; asn1cert.data = s2n_stuffer_raw_read(&cert_chain_in_stuffer, certificate_size); asn1cert.size = certificate_size; if (asn1cert.data == NULL) { return S2N_CERT_ERR_INVALID; } const uint8_t *data = asn1cert.data; if (!validator->skip_cert_validation) { /* the cert is der encoded, just convert it. */ server_cert = d2i_X509(NULL, &data, asn1cert.size); if (!server_cert) { return S2N_CERT_ERR_INVALID; } /* add the cert to the chain. */ if (!sk_X509_push(validator->cert_chain, server_cert)) { X509_free(server_cert); return S2N_CERT_ERR_INVALID; } } /* Pull the public key from the first certificate */ if (certificate_count == 0) { if (s2n_asn1der_to_public_key_and_type(&public_key, cert_type, &asn1cert) < 0) { return S2N_CERT_ERR_INVALID; } } certificate_count++; } /* if this occurred we exceeded validator->max_chain_depth */ if (!validator->skip_cert_validation && s2n_stuffer_data_available(&cert_chain_in_stuffer)) { return S2N_CERT_ERR_MAX_CHAIN_DEPTH_EXCEEDED; } if (certificate_count < 1) { return S2N_CERT_ERR_INVALID; } if (!validator->skip_cert_validation) { X509 *leaf = sk_X509_value(validator->cert_chain, 0); if (!leaf) { return S2N_CERT_ERR_INVALID; } if (conn->verify_host_fn && !s2n_verify_host_information(validator, conn, leaf)) { return S2N_CERT_ERR_UNTRUSTED; } /* now that we have a chain, get the store and check against it. */ ctx = X509_STORE_CTX_new(); int op_code = X509_STORE_CTX_init(ctx, validator->trust_store->trust_store, leaf, validator->cert_chain); if (op_code <= 0) { return S2N_CERT_ERR_INVALID; } X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx); X509_VERIFY_PARAM_set_depth(param, validator->max_chain_depth); uint64_t current_sys_time = 0; conn->config->wall_clock(conn->config->sys_clock_ctx, ¤t_sys_time); /* this wants seconds not nanoseconds */ time_t current_time = (time_t)(current_sys_time / 1000000000); X509_STORE_CTX_set_time(ctx, 0, current_time); op_code = X509_verify_cert(ctx); if (op_code <= 0) { return S2N_CERT_ERR_UNTRUSTED; } } *public_key_out = public_key; /* Reset the old struct, so we don't clean up public_key_out */ s2n_pkey_zero_init(&public_key); return S2N_CERT_OK; }
void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) { check_ssl_ctx_x509_method(ctx); X509_VERIFY_PARAM_set_depth(ctx->param, depth); }
void SSL_set_verify_depth(SSL *ssl, int depth) { check_ssl_x509_method(ssl); X509_VERIFY_PARAM_set_depth(ssl->param, depth); }
static int xmlSecOpenSSLX509StoreInitialize(xmlSecKeyDataStorePtr store) { const xmlChar* path; X509_LOOKUP *lookup = NULL; xmlSecOpenSSLX509StoreCtxPtr ctx; xmlSecAssert2(xmlSecKeyDataStoreCheckId(store, xmlSecOpenSSLX509StoreId), -1); ctx = xmlSecOpenSSLX509StoreGetCtx(store); xmlSecAssert2(ctx != NULL, -1); memset(ctx, 0, sizeof(xmlSecOpenSSLX509StoreCtx)); ctx->xst = X509_STORE_new(); if(ctx->xst == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "X509_STORE_new", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } if(!X509_STORE_set_default_paths(ctx->xst)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "X509_STORE_set_default_paths", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } lookup = X509_STORE_add_lookup(ctx->xst, X509_LOOKUP_hash_dir()); if(lookup == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "X509_STORE_add_lookup", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } path = xmlSecOpenSSLGetDefaultTrustedCertsFolder(); if(path != NULL) { if(!X509_LOOKUP_add_dir(lookup, (char*)path, X509_FILETYPE_PEM)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "X509_LOOKUP_add_dir", XMLSEC_ERRORS_R_CRYPTO_FAILED, "path='%s'", xmlSecErrorsSafeString(path) ); return(-1); } } else { if(!X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT)) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "X509_LOOKUP_add_dir", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE ); return(-1); } } ctx->untrusted = sk_X509_new_null(); if(ctx->untrusted == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "sk_X509_new_null", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } ctx->crls = sk_X509_CRL_new_null(); if(ctx->crls == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "sk_X509_CRL_new_null", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } #if !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) ctx->vpm = X509_VERIFY_PARAM_new(); if(ctx->vpm == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyDataStoreGetName(store)), "X509_VERIFY_PARAM_new", XMLSEC_ERRORS_R_CRYPTO_FAILED, XMLSEC_ERRORS_NO_MESSAGE); return(-1); } X509_VERIFY_PARAM_set_depth(ctx->vpm, 9); /* the default cert verification path in openssl */ X509_STORE_set1_param(ctx->xst, ctx->vpm); #else /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */ ctx->xst->depth = 9; /* the default cert verification path in openssl */ #endif /* !defined(XMLSEC_OPENSSL_096) && !defined(XMLSEC_OPENSSL_097) */ return(0); }