static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf) { STACK_OF(CONF_VALUE) *elist; CONF_VALUE *cval; int i; #ifdef ENGINE_CONF_DEBUG fprintf(stderr, "Called engine module: name %s, value %s\n", CONF_imodule_get_name(md), CONF_imodule_get_value(md)); #endif /* Value is a section containing ENGINEs to configure */ elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); if (!elist) { ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, ENGINE_R_ENGINES_SECTION_ERROR); return 0; } for (i = 0; i < sk_CONF_VALUE_num(elist); i++) { cval = sk_CONF_VALUE_value(elist, i); if (!int_engine_configure(cval->name, cval->value, cnf)) return 0; } return 1; }
static ASN1_TYPE * asn1_multi(int utype, const char *section, X509V3_CTX *cnf) { ASN1_TYPE *ret = NULL; STACK_OF(ASN1_TYPE) *sk = NULL; STACK_OF(CONF_VALUE) *sect = NULL; unsigned char *der = NULL; int derlen; int i; sk = sk_ASN1_TYPE_new_null(); if (!sk) goto bad; if (section) { if (!cnf) goto bad; sect = X509V3_get_section(cnf, (char *)section); if (!sect) goto bad; for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { ASN1_TYPE *typ = ASN1_generate_v3( sk_CONF_VALUE_value(sect, i)->value, cnf); if (!typ) goto bad; if (!sk_ASN1_TYPE_push(sk, typ)) goto bad; } } /* Now we has a STACK of the components, convert to the correct form */ if (utype == V_ASN1_SET) derlen = i2d_ASN1_SET_ANY(sk, &der); else derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); if (derlen < 0) goto bad; if (!(ret = ASN1_TYPE_new())) goto bad; if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) goto bad; ret->type = utype; ret->value.asn1_string->data = der; ret->value.asn1_string->length = derlen; der = NULL; bad: free(der); if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); if (sect) X509V3_section_free(cnf, sect); return ret; }
int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx) { int ret = 0; int i; STACK_OF(CONF_VALUE) *list = NULL; char *digests = NCONF_get_string(conf, section, ENV_DIGESTS); if (!digests) { TS_CONF_lookup_fail(section, ENV_DIGESTS); goto err; } if (!(list = X509V3_parse_list(digests))) { TS_CONF_invalid(section, ENV_DIGESTS); goto err; } if (sk_CONF_VALUE_num(list) == 0) { TS_CONF_invalid(section, ENV_DIGESTS); goto err; } for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { CONF_VALUE *val = sk_CONF_VALUE_value(list, i); const char *extval = val->value ? val->value : val->name; const EVP_MD *md; if (!(md = EVP_get_digestbyname(extval))) { TS_CONF_invalid(section, ENV_DIGESTS); goto err; } if (!TS_RESP_CTX_add_md(ctx, md)) goto err; } ret = 1; err: sk_CONF_VALUE_pop_free(list, X509V3_conf_free); return ret; }
static int set_reasons(ASN1_BIT_STRING **preas, char *value) { STACK_OF(CONF_VALUE) *rsk = NULL; const BIT_STRING_BITNAME *pbn; const char *bnam; int i, ret = 0; rsk = X509V3_parse_list(value); if (!rsk) return 0; if (*preas) return 0; for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) { bnam = sk_CONF_VALUE_value(rsk, i)->name; if (!*preas) { *preas = ASN1_BIT_STRING_new(); if (!*preas) goto err; } for (pbn = reason_flags; pbn->lname; pbn++) { if (strcmp(pbn->sname, bnam) == 0) { if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1)) goto err; break; } } if (!pbn->lname) goto err; } ret = 1; err: sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); return ret; }
static int parse_server_options(SSL_TEST_SERVER_CONF *server, const CONF *conf, const char *server_section) { STACK_OF(CONF_VALUE) *sk_conf; int i; size_t j; sk_conf = NCONF_get_section(conf, server_section); TEST_check(sk_conf != NULL); for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) { int found = 0; const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i); for (j = 0; j < OSSL_NELEM(ssl_test_server_options); j++) { if (strcmp(option->name, ssl_test_server_options[j].name) == 0) { if (!ssl_test_server_options[j].parse(server, option->value)) { fprintf(stderr, "Bad value %s for option %s\n", option->value, option->name); return 0; } found = 1; break; } } if (!found) { fprintf(stderr, "Unknown test option: %s\n", option->name); return 0; } } return 1; }
static int CheckSubjectAltName(X509_EXTENSION *ext, const char *hostname) { STACK_OF(CONF_VALUE) *values; CONF_VALUE *value; const X509V3_EXT_METHOD *meth; unsigned char *data; int len; int ok = FALSE; int i; data = ext->value->data; if ((meth = X509V3_EXT_get(ext)) == NULL) return FALSE; data = ext->value->data; len = ext->value->length; values = meth->i2v(meth, meth->d2i(NULL, (const unsigned char **)&data, len), NULL); if (values == NULL) return FALSE; for (i = 0; i < sk_CONF_VALUE_num(values); i++){ value = sk_CONF_VALUE_value(values, i); if (strcmp(value->name, "DNS") != 0) continue; if (strcasecmp(value->value, hostname) != 0) continue; ok = TRUE; break; } sk_CONF_VALUE_free(values); return ok; }
int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx) { int ret = 0; int i; STACK_OF(CONF_VALUE) *list = NULL; char *policies = NCONF_get_string(conf, section, ENV_OTHER_POLICIES); /* If no other policy is specified, that's fine. */ if (policies && (list = X509V3_parse_list(policies)) == NULL) { ts_CONF_invalid(section, ENV_OTHER_POLICIES); goto err; } for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { CONF_VALUE *val = sk_CONF_VALUE_value(list, i); const char *extval = val->value ? val->value : val->name; ASN1_OBJECT *objtmp; if ((objtmp = OBJ_txt2obj(extval, 0)) == NULL) { ts_CONF_invalid(section, ENV_OTHER_POLICIES); goto err; } if (!TS_RESP_CTX_add_policy(ctx, objtmp)) goto err; ASN1_OBJECT_free(objtmp); } ret = 1; err: sk_CONF_VALUE_pop_free(list, X509V3_conf_free); return ret; }
static int do_tcreate(const char *value, const char *name) { char *eptr; int nid, i, rv = 0; long tbl_min = -1, tbl_max = -1; unsigned long tbl_mask = 0, tbl_flags = 0; STACK_OF(CONF_VALUE) *lst = NULL; CONF_VALUE *cnf = NULL; nid = OBJ_sn2nid(name); if (nid == NID_undef) nid = OBJ_ln2nid(name); if (nid == NID_undef) goto err; lst = X509V3_parse_list(value); if (!lst) goto err; for (i = 0; i < sk_CONF_VALUE_num(lst); i++) { cnf = sk_CONF_VALUE_value(lst, i); if (strcmp(cnf->name, "min") == 0) { tbl_min = strtoul(cnf->value, &eptr, 0); if (*eptr) goto err; } else if (strcmp(cnf->name, "max") == 0) { tbl_max = strtoul(cnf->value, &eptr, 0); if (*eptr) goto err; } else if (strcmp(cnf->name, "mask") == 0) { if (!ASN1_str2mask(cnf->value, &tbl_mask) || !tbl_mask) goto err; } else if (strcmp(cnf->name, "flags") == 0) { if (strcmp(cnf->value, "nomask") == 0) tbl_flags = STABLE_NO_MASK; else if (strcmp(cnf->value, "none") == 0) tbl_flags = STABLE_FLAGS_CLEAR; else goto err; } else goto err; } rv = 1; err: if (rv == 0) { ASN1err(ASN1_F_DO_TCREATE, ASN1_R_INVALID_STRING_TABLE_VALUE); if (cnf) ERR_add_error_data(4, "field=", cnf->name, ", value=", cnf->value); else ERR_add_error_data(4, "name=", name, ", value=", value); } else { rv = ASN1_STRING_TABLE_add(nid, tbl_min, tbl_max, tbl_mask, tbl_flags); if (!rv) ASN1err(ASN1_F_DO_TCREATE, ERR_R_MALLOC_FAILURE); } sk_CONF_VALUE_pop_free(lst, X509V3_conf_free); return rv; }
static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value) { STACK_OF(POLICYINFO) *pols = NULL; char *pstr; POLICYINFO *pol; ASN1_OBJECT *pobj; STACK_OF(CONF_VALUE) *vals; CONF_VALUE *cnf; int i, ia5org; pols = sk_POLICYINFO_new_null(); vals = X509V3_parse_list(value); ia5org = 0; for(i = 0; i < sk_CONF_VALUE_num(vals); i++) { cnf = sk_CONF_VALUE_value(vals, i); if(cnf->value || !cnf->name ) { X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_POLICY_IDENTIFIER); X509V3_conf_err(cnf); goto err; } pstr = cnf->name; if(!strcmp(pstr,"ia5org")) { ia5org = 1; continue; } else if(*pstr == '@') { STACK_OF(CONF_VALUE) *polsect; polsect = X509V3_get_section(ctx, pstr + 1); if(!polsect) { X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_SECTION); X509V3_conf_err(cnf); goto err; } pol = policy_section(ctx, polsect, ia5org); X509V3_section_free(ctx, polsect); if(!pol) goto err; } else { if(!(pobj = OBJ_txt2obj(cnf->name, 0))) { X509V3err(X509V3_F_R2I_CERTPOL,X509V3_R_INVALID_OBJECT_IDENTIFIER); X509V3_conf_err(cnf); goto err; } pol = POLICYINFO_new(); pol->policyid = pobj; } sk_POLICYINFO_push(pols, pol); } sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); return pols; err: sk_POLICYINFO_pop_free(pols, POLICYINFO_free); return NULL; }
static int alg_module_init (CONF_IMODULE * md, const CONF * cnf) { int i; const char *oid_section; STACK_OF (CONF_VALUE) * sktmp; CONF_VALUE *oval; oid_section = CONF_imodule_get_value (md); if (!(sktmp = NCONF_get_section (cnf, oid_section))) { EVPerr (EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION); return 0; } for (i = 0; i < sk_CONF_VALUE_num (sktmp); i++) { oval = sk_CONF_VALUE_value (sktmp, i); if (!strcmp (oval->name, "fips_mode")) { int m; if (!X509V3_get_value_bool (oval, &m)) { EVPerr (EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE); return 0; } if (m > 0) { #ifdef OPENSSL_FIPS if (!FIPS_mode () && !FIPS_mode_set (1)) { EVPerr (EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_SETTING_FIPS_MODE); return 0; } #else EVPerr (EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED); return 0; #endif } } else { EVPerr (EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION); ERR_add_error_data (4, "name=", oval->name, ", value=", oval->value); } } return 1; }
static gboolean ConfigX509CertReq(X509_REQ *req, // OUT CONF *config) // IN { int idx; X509_NAME *subject; gboolean ret = FALSE; const char *dname; gchar *err = NULL; if (!X509_REQ_set_version(req, 0L)) { Error("Failed to set the certificate request version: %s.\n", GetSSLError(&err)); goto exit; } subject = X509_REQ_get_subject_name(req); if (!subject) { Error("Failed to get the certificate request subject name: %s.\n", GetSSLError(&err)); goto exit; } dname = NCONF_get_string(config, "req", "distinguished_name"); if (dname) { STACK_OF(CONF_VALUE) *dn_sk = NCONF_get_section(config, dname); if (!dn_sk) { Error("Failed to get section %s: %s.\n", dname, GetSSLError(&err)); goto exit; } for (idx = 0; idx < sk_CONF_VALUE_num(dn_sk); idx++) { CONF_VALUE *v = sk_CONF_VALUE_value(dn_sk, idx); if (!X509_NAME_add_entry_by_txt(subject, v->name, MBSTRING_ASC, v->value, -1, -1, 0)) { Error("Failed to set certificate request pair %s/%s: %s.\n", v->name, v->value, GetSSLError(&err)); goto exit; } } } ret = TRUE; exit: g_free(err); return ret; }
int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl) { X509_EXTENSION *ext; STACK_OF(CONF_VALUE) *nval; CONF_VALUE *val; int i; if(!(nval = CONF_get_section(conf, section))) return 0; for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { val = sk_CONF_VALUE_value(nval, i); if(!(ext = X509V3_EXT_conf(conf, ctx, val->name, val->value))) return 0; if(crl) X509_CRL_add_ext(crl, ext, -1); X509_EXTENSION_free(ext); } return 1; }
/* TODO(3.0): the config module functions should be passed a library context */ static int alg_module_init(CONF_IMODULE *md, const CONF *cnf) { int i; const char *oid_section; STACK_OF(CONF_VALUE) *sktmp; CONF_VALUE *oval; OSSL_TRACE2(CONF, "Loading EVP module: name %s, value %s\n", CONF_imodule_get_name(md), CONF_imodule_get_value(md)); oid_section = CONF_imodule_get_value(md); if ((sktmp = NCONF_get_section(cnf, oid_section)) == NULL) { EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION); return 0; } for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { oval = sk_CONF_VALUE_value(sktmp, i); if (strcmp(oval->name, "fips_mode") == 0) { int m; if (!X509V3_get_value_bool(oval, &m)) { EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE); return 0; } /* * fips_mode is deprecated and should not be used in new * configurations. Old configurations are likely to ONLY * have this, so we assume that no default properties have * been set before this. */ if (m > 0) EVP_set_default_properties(NULL, "fips=yes"); } else if (strcmp(oval->name, "default_properties") == 0) { EVP_set_default_properties(NULL, oval->value); } else { EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION); ERR_add_error_data(4, "name=", oval->name, ", value=", oval->value); return 0; } } return 1; }
int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx) { int ret = 0; int i; int secs = 0, millis = 0, micros = 0; STACK_OF(CONF_VALUE) *list = NULL; char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY); if (accuracy && !(list = X509V3_parse_list(accuracy))) { TS_CONF_invalid(section, ENV_ACCURACY); goto err; } for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { CONF_VALUE *val = sk_CONF_VALUE_value(list, i); if (strcmp(val->name, ENV_VALUE_SECS) == 0) { if (val->value) secs = atoi(val->value); } else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0) { if (val->value) millis = atoi(val->value); } else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0) { if (val->value) micros = atoi(val->value); } else { TS_CONF_invalid(section, ENV_ACCURACY); goto err; } } if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros)) goto err; ret = 1; err: sk_CONF_VALUE_pop_free(list, X509V3_conf_free); return ret; }
static int oid_module_init(CONF_IMODULE *md, const CONF *cnf) { int i; const char *oid_section; STACK_OF(CONF_VALUE) *sktmp; CONF_VALUE *oval; oid_section = CONF_imodule_get_value(md); if (!(sktmp = NCONF_get_section(cnf, oid_section))) { ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION); return 0; } for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { oval = sk_CONF_VALUE_value(sktmp, i); if (!do_create(oval->value, oval->name)) { ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT); return 0; } } return 1; }
SSL_TEST_CTX *SSL_TEST_CTX_create(const CONF *conf, const char *test_section) { STACK_OF(CONF_VALUE) *sk_conf; SSL_TEST_CTX *ctx; int i; size_t j; sk_conf = NCONF_get_section(conf, test_section); OPENSSL_assert(sk_conf != NULL); ctx = SSL_TEST_CTX_new(); OPENSSL_assert(ctx != NULL); for (i = 0; i < sk_CONF_VALUE_num(sk_conf); i++) { int found = 0; const CONF_VALUE *option = sk_CONF_VALUE_value(sk_conf, i); for (j = 0; j < OSSL_NELEM(ssl_test_ctx_options); j++) { if (strcmp(option->name, ssl_test_ctx_options[j].name) == 0) { if (!ssl_test_ctx_options[j].parse(ctx, option->value)) { fprintf(stderr, "Bad value %s for option %s\n", option->value, option->name); goto err; } found = 1; break; } } if (!found) { fprintf(stderr, "Unknown test option: %s\n", option->name); goto err; } } goto done; err: SSL_TEST_CTX_free(ctx); ctx = NULL; done: return ctx; }
static int stbl_module_init(CONF_IMODULE *md, const CONF *cnf) { int i; const char *stbl_section; STACK_OF(CONF_VALUE) *sktmp; CONF_VALUE *mval; stbl_section = CONF_imodule_get_value(md); if ((sktmp = NCONF_get_section(cnf, stbl_section)) == NULL) { ASN1err(ASN1_F_STBL_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION); return 0; } for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { mval = sk_CONF_VALUE_value(sktmp, i); if (!do_tcreate(mval->value, mval->name)) { ASN1err(ASN1_F_STBL_MODULE_INIT, ASN1_R_INVALID_VALUE); return 0; } } return 1; }
int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_REQ *req) { X509_EXTENSION *ext; STACK_OF(X509_EXTENSION) *extlist = NULL; STACK_OF(CONF_VALUE) *nval; CONF_VALUE *val; int i; if(!(nval = CONF_get_section(conf, section))) return 0; for(i = 0; i < sk_CONF_VALUE_num(nval); i++) { val = sk_CONF_VALUE_value(nval, i); if(!(ext = X509V3_EXT_conf(conf, ctx, val->name, val->value))) return 0; if(!extlist) extlist = sk_X509_EXTENSION_new_null(); sk_X509_EXTENSION_push(extlist, ext); } if(req) i = X509_REQ_add_extensions(req, extlist); else i = 1; sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); return i; }
static int verify_cert_hostname(X509 *cert, char *hostname) { int extcount, i, j, ok = 0; char name[256]; X509_NAME *subj; const char *extstr; CONF_VALUE *nval; const unsigned char *data; X509_EXTENSION *ext; X509V3_EXT_METHOD *meth; STACK_OF(CONF_VALUE) *val; if ((extcount = X509_get_ext_count(cert)) > 0) { for (i = 0; !ok && i < extcount; i++) { ext = X509_get_ext(cert, i); extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); if (!strcasecmp(extstr, "subjectAltName")) { if (!(meth = (X509V3_EXT_METHOD *)X509V3_EXT_get(ext))) break; data = ext->value->data; val = meth->i2v(meth, meth->d2i(0, &data, ext->value->length), 0); for (j = 0; j < sk_CONF_VALUE_num(val); j++) { nval = sk_CONF_VALUE_value(val, j); if (!strcasecmp(nval->name, "DNS") && !strcasecmp(nval->value, hostname)) { ok = 1; break; } } } } } if (!ok && (subj = X509_get_subject_name(cert)) && X509_NAME_get_text_by_NID(subj, NID_commonName, name, sizeof(name)) > 0) { name[sizeof(name) - 1] = '\0'; if (!strcasecmp(name, hostname)) ok = 1; } return ok; }
int main(int argc, char **argv) { BIO *sbio = NULL, *out = NULL; int i, len, rv; char tmpbuf[1024]; SSL_CTX *ctx = NULL; SSL_CONF_CTX *cctx = NULL; SSL *ssl = NULL; CONF *conf = NULL; STACK_OF(CONF_VALUE) *sect = NULL; CONF_VALUE *cnf; const char *connect_str = "localhost:4433"; long errline = -1; ERR_load_crypto_strings(); ERR_load_SSL_strings(); SSL_library_init(); conf = NCONF_new(NULL); if (NCONF_load(conf, "connect.cnf", &errline) <= 0) { if (errline <= 0) fprintf(stderr, "Error processing config file\n"); else fprintf(stderr, "Error on line %ld\n", errline); goto end; } sect = NCONF_get_section(conf, "default"); if (sect == NULL) { fprintf(stderr, "Error retrieving default section\n"); goto end; } ctx = SSL_CTX_new(SSLv3_client_method()); cctx = SSL_CONF_CTX_new(); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { cnf = sk_CONF_VALUE_value(sect, i); rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value); if (rv > 0) continue; if (rv != -2) { fprintf(stderr, "Error processing %s = %s\n", cnf->name, cnf->value); ERR_print_errors_fp(stderr); goto end; } if (!strcmp(cnf->name, "Connect")) { connect_str = cnf->value; } else { fprintf(stderr, "Unknown configuration option %s\n", cnf->name); goto end; } } if (!SSL_CONF_CTX_finish(cctx)) { fprintf(stderr, "Finish error\n"); ERR_print_errors_fp(stderr); goto err; } /* * We'd normally set some stuff like the verify paths and * mode here * because as things stand this will connect to * any server whose * certificate is signed by any CA. */ sbio = BIO_new_ssl_connect(ctx); BIO_get_ssl(sbio, &ssl); if (!ssl) { fprintf(stderr, "Can't locate SSL pointer\n"); goto end; } /* Don't want any retries */ SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); /* We might want to do other things with ssl here */ BIO_set_conn_hostname(sbio, connect_str); out = BIO_new_fp(stdout, BIO_NOCLOSE); if (BIO_do_connect(sbio) <= 0) { fprintf(stderr, "Error connecting to server\n"); ERR_print_errors_fp(stderr); goto end; } if (BIO_do_handshake(sbio) <= 0) { fprintf(stderr, "Error establishing SSL connection\n"); ERR_print_errors_fp(stderr); goto end; } /* Could examine ssl here to get connection info */ BIO_puts(sbio, "GET / HTTP/1.0\n\n"); for (;;) { len = BIO_read(sbio, tmpbuf, 1024); if (len <= 0) break; BIO_write(out, tmpbuf, len); } end: SSL_CONF_CTX_free(cctx); BIO_free_all(sbio); BIO_free(out); NCONF_free(conf); return 0; }
int main(int argc, char *argv[]) { char *port = "*:4433"; BIO *in = NULL; BIO *ssl_bio, *tmp; SSL_CTX *ctx; SSL_CONF_CTX *cctx = NULL; CONF *conf = NULL; STACK_OF(CONF_VALUE) *sect = NULL; CONF_VALUE *cnf; long errline = -1; char buf[512]; int ret = EXIT_FAILURE, i; ctx = SSL_CTX_new(TLS_server_method()); conf = NCONF_new(NULL); if (NCONF_load(conf, "accept.cnf", &errline) <= 0) { if (errline <= 0) fprintf(stderr, "Error processing config file\n"); else fprintf(stderr, "Error on line %ld\n", errline); goto err; } sect = NCONF_get_section(conf, "default"); if (sect == NULL) { fprintf(stderr, "Error retrieving default section\n"); goto err; } cctx = SSL_CONF_CTX_new(); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_SERVER); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CERTIFICATE); SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE); SSL_CONF_CTX_set_ssl_ctx(cctx, ctx); for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { int rv; cnf = sk_CONF_VALUE_value(sect, i); rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value); if (rv > 0) continue; if (rv != -2) { fprintf(stderr, "Error processing %s = %s\n", cnf->name, cnf->value); ERR_print_errors_fp(stderr); goto err; } if (strcmp(cnf->name, "Port") == 0) { port = cnf->value; } else { fprintf(stderr, "Unknown configuration option %s\n", cnf->name); goto err; } } if (!SSL_CONF_CTX_finish(cctx)) { fprintf(stderr, "Finish error\n"); ERR_print_errors_fp(stderr); goto err; } /* Setup server side SSL bio */ ssl_bio = BIO_new_ssl(ctx, 0); if ((in = BIO_new_accept(port)) == NULL) goto err; /* * This means that when a new connection is accepted on 'in', The ssl_bio * will be 'duplicated' and have the new socket BIO push into it. * Basically it means the SSL BIO will be automatically setup */ BIO_set_accept_bios(in, ssl_bio); again: /* * The first call will setup the accept socket, and the second will get a * socket. In this loop, the first actual accept will occur in the * BIO_read() function. */ if (BIO_do_accept(in) <= 0) goto err; for (;;) { i = BIO_read(in, buf, 512); if (i == 0) { /* * If we have finished, remove the underlying BIO stack so the * next time we call any function for this BIO, it will attempt * to do an accept */ printf("Done\n"); tmp = BIO_pop(in); BIO_free_all(tmp); goto again; } if (i < 0) { if (BIO_should_retry(in)) continue; goto err; } fwrite(buf, 1, i, stdout); fflush(stdout); } ret = EXIT_SUCCESS; err: if (ret != EXIT_SUCCESS) ERR_print_errors_fp(stderr); BIO_free(in); return ret; }
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf) { ASN1_TYPE *ret = NULL, *typ = NULL; STACK_OF(ASN1_TYPE) *sk = NULL; STACK_OF(CONF_VALUE) *sect = NULL; unsigned char *der = NULL, *p; int derlen; int i, is_set; sk = sk_ASN1_TYPE_new_null(); if (section) { if (!cnf) goto bad; sect = X509V3_get_section(cnf, (char *)section); if (!sect) goto bad; for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { typ = ASN1_generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf); if (!typ) goto bad; sk_ASN1_TYPE_push(sk, typ); typ = NULL; } } /* Now we has a STACK of the components, convert to the correct form */ if (utype == V_ASN1_SET) is_set = 1; else is_set = 0; derlen = i2d_ASN1_SET_OF_ASN1_TYPE(sk, NULL, i2d_ASN1_TYPE, utype, V_ASN1_UNIVERSAL, is_set); der = OPENSSL_malloc(derlen); p = der; i2d_ASN1_SET_OF_ASN1_TYPE(sk, &p, i2d_ASN1_TYPE, utype, V_ASN1_UNIVERSAL, is_set); if (!(ret = ASN1_TYPE_new())) goto bad; if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) goto bad; ret->type = utype; ret->value.asn1_string->data = der; ret->value.asn1_string->length = derlen; der = NULL; bad: if (der) OPENSSL_free(der); if (sk) sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); if (typ) ASN1_TYPE_free(typ); if (sect) X509V3_section_free(cnf, sect); return ret; }
static int ssl_module_init(CONF_IMODULE *md, const CONF *cnf) { size_t i, j, cnt; int rv = 0; const char *ssl_conf_section; STACK_OF(CONF_VALUE) *cmd_lists; ssl_conf_section = CONF_imodule_get_value(md); cmd_lists = NCONF_get_section(cnf, ssl_conf_section); if (sk_CONF_VALUE_num(cmd_lists) <= 0) { if (cmd_lists == NULL) CONFerr(CONF_F_SSL_MODULE_INIT, CONF_R_SSL_SECTION_NOT_FOUND); else CONFerr(CONF_F_SSL_MODULE_INIT, CONF_R_SSL_SECTION_EMPTY); ERR_add_error_data(2, "section=", ssl_conf_section); goto err; } cnt = sk_CONF_VALUE_num(cmd_lists); ssl_module_free(md); ssl_names = OPENSSL_zalloc(sizeof(*ssl_names) * cnt); if (ssl_names == NULL) goto err; ssl_names_count = cnt; for (i = 0; i < ssl_names_count; i++) { struct ssl_conf_name_st *ssl_name = ssl_names + i; CONF_VALUE *sect = sk_CONF_VALUE_value(cmd_lists, (int)i); STACK_OF(CONF_VALUE) *cmds = NCONF_get_section(cnf, sect->value); if (sk_CONF_VALUE_num(cmds) <= 0) { if (cmds == NULL) CONFerr(CONF_F_SSL_MODULE_INIT, CONF_R_SSL_COMMAND_SECTION_NOT_FOUND); else CONFerr(CONF_F_SSL_MODULE_INIT, CONF_R_SSL_COMMAND_SECTION_EMPTY); ERR_add_error_data(4, "name=", sect->name, ", value=", sect->value); goto err; } ssl_name->name = OPENSSL_strdup(sect->name); if (ssl_name->name == NULL) goto err; cnt = sk_CONF_VALUE_num(cmds); ssl_name->cmds = OPENSSL_zalloc(cnt * sizeof(struct ssl_conf_cmd_st)); if (ssl_name->cmds == NULL) goto err; ssl_name->cmd_count = cnt; for (j = 0; j < cnt; j++) { const char *name; CONF_VALUE *cmd_conf = sk_CONF_VALUE_value(cmds, (int)j); struct ssl_conf_cmd_st *cmd = ssl_name->cmds + j; /* Skip any initial dot in name */ name = strchr(cmd_conf->name, '.'); if (name != NULL) name++; else name = cmd_conf->name; cmd->cmd = OPENSSL_strdup(name); cmd->arg = OPENSSL_strdup(cmd_conf->value); if (cmd->cmd == NULL || cmd->arg == NULL) goto err; } } rv = 1; err: if (rv == 0) ssl_module_free(md); return rv; }
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; }
su_inline int tls_post_connection_check(tport_t *self, tls_t *tls) { X509 *cert; int extcount; int i, j, error; if (!tls) return -1; cert = SSL_get_peer_certificate(tls->con); if (!cert) { SU_DEBUG_7(("%s(%p): Peer did not provide X.509 Certificate.\n", __func__, (void *) self)); if (self->tp_accepted && tls->verify_incoming) return X509_V_ERR_CERT_UNTRUSTED; else if (!self->tp_accepted && tls->verify_outgoing) return X509_V_ERR_CERT_UNTRUSTED; else return X509_V_OK; } tls->subjects = su_strlst_create(tls->home); if (!tls->subjects) return X509_V_ERR_OUT_OF_MEM; extcount = X509_get_ext_count(cert); /* Find matching subjectAltName.DNS */ for (i = 0; i < extcount; i++) { X509_EXTENSION *ext; char const *name; #if OPENSSL_VERSION_NUMBER > 0x10000000L const X509V3_EXT_METHOD *vp; #else X509V3_EXT_METHOD *vp; #endif STACK_OF(CONF_VALUE) *values; CONF_VALUE *value; void *d2i; ext = X509_get_ext(cert, i); name = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); if (strcmp(name, "subjectAltName") != 0) continue; vp = X509V3_EXT_get(ext); if (!vp) continue; d2i = X509V3_EXT_d2i(ext); values = vp->i2v(vp, d2i, NULL); for (j = 0; j < sk_CONF_VALUE_num(values); j++) { value = sk_CONF_VALUE_value(values, j); if (strcmp(value->name, "DNS") == 0) su_strlst_dup_append(tls->subjects, value->value); if (strcmp(value->name, "IP") == 0) su_strlst_dup_append(tls->subjects, value->value); else if (strcmp(value->name, "URI") == 0) su_strlst_dup_append(tls->subjects, value->value); } } { X509_NAME *subject; char name[256]; subject = X509_get_subject_name(cert); if (subject) { if (X509_NAME_get_text_by_NID(subject, NID_commonName, name, sizeof name) > 0) { usize_t k, N = su_strlst_len(tls->subjects); name[(sizeof name) - 1] = '\0'; for (k = 0; k < N; k++) if (su_casematch(su_strlst_item(tls->subjects, k), name) == 0) break; if (k >= N) su_strlst_dup_append(tls->subjects, name); } } } X509_free(cert); error = SSL_get_verify_result(tls->con); if (cert && error == X509_V_OK) tls->x509_verified = 1; if (tport_log->log_level >= 7) { int i, len = su_strlst_len(tls->subjects); for (i=0; i < len; i++) SU_DEBUG_7(("%s(%p): Peer Certificate Subject %i: %s\n", \ __func__, (void *)self, i, su_strlst_item(tls->subjects, i))); if (i == 0) SU_DEBUG_7(("%s(%p): Peer Certificate provided no usable subjects.\n", __func__, (void *)self)); } /* Verify incoming connections */ if (self->tp_accepted) { if (!tls->verify_incoming) return X509_V_OK; if (!tls->x509_verified) return error; if (tls->verify_subj_in) { su_strlst_t const *subjects = self->tp_pri->pri_primary->tp_subjects; int i, items; items = subjects ? su_strlst_len(subjects) : 0; if (items == 0) return X509_V_OK; for (i=0; i < items; i++) { if (tport_subject_search(su_strlst_item(subjects, i), tls->subjects)) return X509_V_OK; } SU_DEBUG_3(("%s(%p): Peer Subject Mismatch (incoming connection)\n", \ __func__, (void *)self)); return X509_V_ERR_CERT_UNTRUSTED; } } /* Verify outgoing connections */ else { char const *subject = self->tp_canon; if (!tls->verify_outgoing) return X509_V_OK; if (!tls->x509_verified || !subject) return error; if (tls->verify_subj_out) { if (tport_subject_search(subject, tls->subjects)) return X509_V_OK; /* Subject match found in verified certificate chain */ SU_DEBUG_3(("%s(%p): Peer Subject Mismatch (%s)\n", \ __func__, (void *)self, subject)); return X509_V_ERR_CERT_UNTRUSTED; } } return error; }
/** Search for a hostname match in the SubjectAlternativeNames. */ uint32_t check_san (SSL *ssl, const char *hostname) { X509 *cert; int extcount, ok = 0; /* What an OpenSSL mess ... */ if (NULL == (cert = SSL_get_peer_certificate(ssl))) { die ("Getting certificate failed"); } if ((extcount = X509_get_ext_count(cert)) > 0) { int i; for (i = 0; i < extcount; ++i) { const char *extstr; X509_EXTENSION *ext; ext = X509_get_ext(cert, i); extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); if (!strcmp(extstr, "subjectAltName")) { int j; void *extvalstr; const unsigned char *tmp; STACK_OF(CONF_VALUE) *val; CONF_VALUE *nval; #if OPENSSL_VERSION_NUMBER >= 0x10000000L const #endif X509V3_EXT_METHOD *method; if (!(method = X509V3_EXT_get(ext))) { break; } tmp = ext->value->data; if (method->it) { extvalstr = ASN1_item_d2i(NULL, &tmp, ext->value->length, ASN1_ITEM_ptr(method->it)); } else { extvalstr = method->d2i(NULL, &tmp, ext->value->length); } if (!extvalstr) { break; } if (method->i2v) { val = method->i2v(method, extvalstr, NULL); for (j = 0; j < sk_CONF_VALUE_num(val); ++j) { nval = sk_CONF_VALUE_value(val, j); if ((!strcasecmp(nval->name, "DNS") && !strcasecmp(nval->value, hostname) ) || (!strcasecmp(nval->name, "iPAddress") && !strcasecmp(nval->value, hostname))) { verb ("V: subjectAltName matched: %s, type: %s", nval->value, nval->name); // We matched this; so it's safe to print ok = 1; break; } // Attempt to match subjectAltName DNS names if (!strcasecmp(nval->name, "DNS")) { ok = check_wildcard_match_rfc2595(hostname, nval->value); if (ok) { break; } } verb_debug ("V: subjectAltName found but not matched: %s, type: %s", nval->value, sanitize_string(nval->name)); } } } else { verb_debug ("V: found non subjectAltName extension"); } if (ok) { break; } } } else { verb_debug ("V: no X509_EXTENSION field(s) found"); } X509_free(cert); return ok; }
PKI_STACK *PKI_X509_CERT_get_cdp (const PKI_X509_CERT *x) { STACK_OF(DIST_POINT) *sk_cdp = NULL; DIST_POINT *cdp = NULL; STACK_OF(CONF_VALUE) *sk_val = NULL; CONF_VALUE *v = NULL; PKI_STACK *ret = NULL; PKI_X509_CERT_VALUE *cert = NULL; char *tmp_s = NULL; int k = -1; int i = 0; if ( !x || !x->value ) return NULL; cert = (PKI_X509_CERT_VALUE *) x->value; if(( sk_cdp = X509_get_ext_d2i(cert, NID_crl_distribution_points, NULL, NULL)) == NULL ) { return NULL; } /* Should we go through the whole stack ? Maybe, now we just take the first value... */ if ( sk_DIST_POINT_num ( sk_cdp ) < 1 ) { return NULL; } for ( i = 0 ; i < sk_DIST_POINT_num ( sk_cdp ); i++ ) { cdp = sk_DIST_POINT_value ( sk_cdp, i ); if( cdp->distpoint ) { if(cdp->distpoint->type == 0) { if( cdp->distpoint->name.fullname ) { sk_val = i2v_GENERAL_NAMES(NULL, cdp->distpoint->name.fullname, sk_val); k=0; for( ;; ) { v = sk_CONF_VALUE_value( sk_val, k++ ); if( v == NULL ) break; if( strncmp_nocase("URI", v->name, 3) == 0 ) { PKI_log_debug( "INFO::Found " "CDP in cert %s:%s", v->name, v->value ); if (!ret) { ret = PKI_STACK_new_null (); if (!ret) return NULL; } tmp_s = strdup( v->value ); PKI_STACK_push ( ret, tmp_s ); } } // sk_CONF_VALUE_free(sk_val); } } // else { // DIST_POINT_free( cdp ); // sk_DIST_POINT_free( sk_cdp ); //} } } return ret; }
static int int_engine_configure(char *name, char *value, const CONF *cnf) { int i; int ret = 0; long do_init = -1; STACK_OF(CONF_VALUE) *ecmds; CONF_VALUE *ecmd; char *ctrlname, *ctrlvalue; ENGINE *e = NULL; name = skip_dot(name); #ifdef ENGINE_CONF_DEBUG fprintf(stderr, "Configuring engine %s\n", name); #endif /* Value is a section containing ENGINE commands */ ecmds = NCONF_get_section(cnf, value); if (!ecmds) { ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_ENGINE_SECTION_ERROR); return 0; } for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) { ecmd = sk_CONF_VALUE_value(ecmds, i); ctrlname = skip_dot(ecmd->name); ctrlvalue = ecmd->value; #ifdef ENGINE_CONF_DEBUG fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, ctrlvalue); #endif /* First handle some special pseudo ctrls */ /* Override engine name to use */ if (!strcmp(ctrlname, "engine_id")) name = ctrlvalue; /* Load a dynamic ENGINE */ else if (!strcmp(ctrlname, "dynamic_path")) { e = ENGINE_by_id("dynamic"); if (!e) goto err; if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0)) goto err; if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0)) goto err; if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) goto err; } /* ... add other pseudos here ... */ else { /* At this point we need an ENGINE structural reference * if we don't already have one. */ if (!e) { e = ENGINE_by_id(name); if (!e) return 0; } /* Allow "EMPTY" to mean no value: this allows a valid * "value" to be passed to ctrls of type NO_INPUT */ if (!strcmp(ctrlvalue, "EMPTY")) ctrlvalue = NULL; if (!strcmp(ctrlname, "init")) { if (!NCONF_get_number_e(cnf, value, "init", &do_init)) goto err; if (do_init == 1) { if (!int_engine_init(e)) goto err; } else if (do_init != 0) { ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, ENGINE_R_INVALID_INIT_VALUE); goto err; } } else if (!strcmp(ctrlname, "default_algorithms")) { if (!ENGINE_set_default_string(e, ctrlvalue)) goto err; } else if (!ENGINE_ctrl_cmd_string(e, ctrlname, ctrlvalue, 0)) return 0; } } if (e && (do_init == -1) && !int_engine_init(e)) goto err; ret = 1; err: if (e) ENGINE_free(e); return ret; }
/* * Check that the common name matches the host name */ static int check_cert_chain(conn_t * conn, SSL * ssl, ruleset_t * rs) { X509 *peer; X509_NAME *xn; static char subject[1024]; int r = FALSE, extc; if (SSL_get_verify_result(ssl) != X509_V_OK) { LOG(SPOCP_ERR) traceLog(LOG_ERR,"Certificate doesn't verify"); return FALSE; } /* * Check the cert chain. The chain length is automatically checked by * OpenSSL when we set the verify depth in the ctx */ peer = SSL_get_peer_certificate(ssl); if (!peer) { LOG(SPOCP_ERR) traceLog(LOG_ERR,"No peer certificate"); return TRUE; } /* * check subjectaltname */ if ((extc = X509_get_ext_count(peer)) > 0) { int i; for (i = 0; r == FALSE && i < extc; i++) { X509_EXTENSION *ext; const char *extstr; ext = X509_get_ext(peer, i); extstr = OBJ_nid2sn(OBJ_obj2nid (X509_EXTENSION_get_object(ext))); if (strcmp(extstr, "subjectAltName") == 0) { int j; unsigned char *data; STACK_OF(CONF_VALUE) * val; CONF_VALUE *nval; X509V3_EXT_METHOD *meth; if ((meth = X509V3_EXT_get(ext)) == 0) break; data = ext->value->data; val = meth->i2v(meth, meth->d2i(NULL, &data, ext->value->length), NULL); for (j = 0; r == FALSE && i < sk_CONF_VALUE_num(val); j++) { nval = sk_CONF_VALUE_value(val, j); if (strcasecmp(nval->name, "DNS") == 0 && strcasecmp(nval->value, conn->sri. hostname)) { r = TRUE; } } } } } if (r == FALSE) { /* * Check the subject name */ xn = X509_get_subject_name(peer); X509_NAME_get_text_by_NID(xn, NID_commonName, subject, 1024); subject[1023] = '\0'; traceLog(LOG_DEBUG,"\"%s\" = \"%s\" ?", subject, conn->sri.hostname); if (strcasecmp(subject, conn->sri.hostname) == 0) { r = TRUE; } } if (r == TRUE) { conn->subjectDN = X509_NAME_oneline(X509_get_subject_name(peer), NULL, 0); conn->issuerDN = X509_NAME_oneline(X509_get_issuer_name(peer), NULL, 0); } X509_free(peer); return r; }
//extention to SSL_get_verify_result int CSSLClient::PostConnectCheck(SSL *ssl, const char *pHost) { X509 *cert; X509_NAME *subj; char data[256]; int extcount; int ret = 0; do { if (!(cert = SSL_get_peer_certificate(ssl)) || !pHost) { break; } if ((extcount = X509_get_ext_count(cert)) > 0) { int i; for (i = 0; i < extcount; i++) { const char *extstr; X509_EXTENSION *ext; ext = X509_get_ext(cert, i); extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext))); if (!strcmp(extstr, SN_subject_alt_name)) { int j; const unsigned char *pData; STACK_OF(CONF_VALUE) *val; CONF_VALUE *nval; const X509V3_EXT_METHOD *pExtMethod; if (!(pExtMethod = X509V3_EXT_get(ext))) { break; } pData = ext->value->data; val = pExtMethod->i2v(pExtMethod, pExtMethod->d2i(NULL, &pData, ext->value->length), NULL); for (j = 0; j < sk_CONF_VALUE_num(val); j++) { nval = sk_CONF_VALUE_value(val, j); if (!strcmp(nval->name, "DNS") && !strcmp(nval->value, pHost)) { ret = 1; break; } } } if (ret) { break; } }//end of for(; extentcount; ) } if (!ret && (subj = X509_get_subject_name(cert)) && X509_NAME_get_text_by_NID(subj, NID_commonName, data, 256) > 0) { data[255] = 0; if (strcmp(data, pHost) != 0) { break; } } X509_free(cert); ret = SSL_get_verify_result(ssl); return ret; } while(0); if (cert) { X509_free(cert); } return -1; }