void OpenSSLCertificate::parse() {
	if (!cert) {
		return;
	}

	// Subject name
	X509_NAME* subjectName = X509_get_subject_name(cert.get());
	if (subjectName) {
		// Subject name
		ByteArray subjectNameData;
		subjectNameData.resize(256);
		X509_NAME_oneline(X509_get_subject_name(cert.get()), reinterpret_cast<char*>(subjectNameData.getData()), subjectNameData.getSize());
		this->subjectName = std::string(reinterpret_cast<const char*>(subjectNameData.getData()));

		// Common name
		int cnLoc = X509_NAME_get_index_by_NID(subjectName, NID_commonName, -1);
		while (cnLoc != -1) {
			X509_NAME_ENTRY* cnEntry = X509_NAME_get_entry(subjectName, cnLoc);
			ASN1_STRING* cnData = X509_NAME_ENTRY_get_data(cnEntry);
			commonNames.push_back(ByteArray(cnData->data, cnData->length).toString());
			cnLoc = X509_NAME_get_index_by_NID(subjectName, NID_commonName, cnLoc);
		}
	}

	// subjectAltNames
	int subjectAltNameLoc = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1);
	if(subjectAltNameLoc != -1) {
		X509_EXTENSION* extension = X509_get_ext(cert.get(), subjectAltNameLoc);
		boost::shared_ptr<GENERAL_NAMES> generalNames(reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(extension)), GENERAL_NAMES_free);
		boost::shared_ptr<ASN1_OBJECT> xmppAddrObject(OBJ_txt2obj(ID_ON_XMPPADDR_OID, 1), ASN1_OBJECT_free);
		boost::shared_ptr<ASN1_OBJECT> dnsSRVObject(OBJ_txt2obj(ID_ON_DNSSRV_OID, 1), ASN1_OBJECT_free);
		for (int i = 0; i < sk_GENERAL_NAME_num(generalNames.get()); ++i) {
			GENERAL_NAME* generalName = sk_GENERAL_NAME_value(generalNames.get(), i);
			if (generalName->type == GEN_OTHERNAME) {
				OTHERNAME* otherName = generalName->d.otherName;
				if (OBJ_cmp(otherName->type_id, xmppAddrObject.get()) == 0) {
					// XmppAddr
					if (otherName->value->type != V_ASN1_UTF8STRING) {
						continue;
					}
					ASN1_UTF8STRING* xmppAddrValue = otherName->value->value.utf8string;
					addXMPPAddress(ByteArray(ASN1_STRING_data(xmppAddrValue), ASN1_STRING_length(xmppAddrValue)).toString());
				}
				else if (OBJ_cmp(otherName->type_id, dnsSRVObject.get()) == 0) {
					// SRVName
					if (otherName->value->type != V_ASN1_IA5STRING) {
						continue;
					}
					ASN1_IA5STRING* srvNameValue = otherName->value->value.ia5string;
					addSRVName(ByteArray(ASN1_STRING_data(srvNameValue), ASN1_STRING_length(srvNameValue)).toString());
				}
			}
			else if (generalName->type == GEN_DNS) {
				// DNSName
				addDNSName(ByteArray(ASN1_STRING_data(generalName->d.dNSName), ASN1_STRING_length(generalName->d.dNSName)).toString());
			}
		}
	}
}
示例#2
0
/*
 * For each name in the cert. Iterate them. Call the callback. If one returns true, then consider it validated,
 * if none of them return true, the cert is considered invalid.
 */
static uint8_t s2n_verify_host_information(struct s2n_x509_validator *validator, struct s2n_connection *conn, X509 *public_cert) {
    uint8_t verified = 0;
    uint8_t san_found = 0;

    /* Check SubjectAltNames before CommonName as per RFC 6125 6.4.4 */
    STACK_OF(GENERAL_NAME) *names_list = X509_get_ext_d2i(public_cert, NID_subject_alt_name, NULL, NULL);
    int n = sk_GENERAL_NAME_num(names_list);
    for (int i = 0; i < n && !verified; i++) {
        GENERAL_NAME *current_name = sk_GENERAL_NAME_value(names_list, i);
        if (current_name->type == GEN_DNS) {
            san_found = 1;

            const char *name = (const char *) ASN1_STRING_data(current_name->d.ia5);
            size_t name_len = (size_t) ASN1_STRING_length(current_name->d.ia5);

            verified = conn->verify_host_fn(name, name_len, conn->data_for_verify_host);
        }
    }

    GENERAL_NAMES_free(names_list);

    /* if no SubjectAltNames of type DNS found, go to the common name. */
    if (!san_found) {
        X509_NAME *subject_name = X509_get_subject_name(public_cert);
        if (subject_name) {
            int next_idx = 0, curr_idx = -1;
            while ((next_idx = X509_NAME_get_index_by_NID(subject_name, NID_commonName, curr_idx)) >= 0) {
                curr_idx = next_idx;
            }

            if (curr_idx >= 0) {
                ASN1_STRING *common_name =
                        X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, curr_idx));

                if (common_name) {
                    char peer_cn[255];
                    static size_t peer_cn_size = sizeof(peer_cn);
                    memset_check(&peer_cn, 0, peer_cn_size);
                    
                    // X520CommonName allows the following ANSI string types per RFC 5280 Appendix A.1
                    if (ASN1_STRING_type(common_name) == V_ASN1_TELETEXSTRING || 
                        ASN1_STRING_type(common_name) == V_ASN1_PRINTABLESTRING ||
                        ASN1_STRING_type(common_name) == V_ASN1_UNIVERSALSTRING ||
                        ASN1_STRING_type(common_name) == V_ASN1_UTF8STRING ||
                        ASN1_STRING_type(common_name) == V_ASN1_BMPSTRING ) {

                        size_t len = (size_t) ASN1_STRING_length(common_name);

                        lte_check(len, sizeof(peer_cn) - 1);
                        memcpy_check(peer_cn, ASN1_STRING_data(common_name), len);
                        verified = conn->verify_host_fn(peer_cn, len, conn->data_for_verify_host);
                    }
                }
            }
        }
    }

    return verified;
}
示例#3
0
文件: tls_mosq.c 项目: yashh/MQTTKit
/* This code is based heavily on the example provided in "Secure Programming
 * Cookbook for C and C++".
 */
int _mosquitto_verify_certificate_hostname(X509 *cert, const char *hostname)
{
	int i;
	char name[256];
	X509_NAME *subj;
	bool have_san_dns = false;
	STACK_OF(GENERAL_NAME) *san;
	const GENERAL_NAME *nval;
	const unsigned char *data;
	unsigned char ipv6_addr[16];
	unsigned char ipv4_addr[4];
	int ipv6_ok;
	int ipv4_ok;

#ifdef WIN32
	ipv6_ok = InetPton(AF_INET6, hostname, &ipv6_addr);
	ipv4_ok = InetPton(AF_INET, hostname, &ipv4_addr);
#else
	ipv6_ok = inet_pton(AF_INET6, hostname, &ipv6_addr);
	ipv4_ok = inet_pton(AF_INET, hostname, &ipv4_addr);
#endif

	san = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
	if(san){
		for(i=0; i<sk_GENERAL_NAME_num(san); i++){
			nval = sk_GENERAL_NAME_value(san, i);
			if(nval->type == GEN_DNS){
				data = ASN1_STRING_data(nval->d.dNSName);
				if(data && match_hostname((char *)data, hostname)){
					return 1;
				}
				have_san_dns = true;
			}else if(nval->type == GEN_IPADD){
				data = ASN1_STRING_data(nval->d.iPAddress);
				if(nval->d.iPAddress->length == 4 && ipv4_ok){
					if(!memcmp(ipv4_addr, data, 4)){
						return 1;
					}
				}else if(nval->d.iPAddress->length == 16 && ipv6_ok){
					if(!memcmp(ipv6_addr, data, 16)){
						return 1;
					}
				}
			}
		}
		if(have_san_dns){
			/* Only check CN if subjectAltName DNS entry does not exist. */
			return 0;
		}
	}
	subj = X509_get_subject_name(cert);
	if(X509_NAME_get_text_by_NID(subj, NID_commonName, name, sizeof(name)) > 0){
		name[sizeof(name) - 1] = '\0';
		if (!strcasecmp(name, hostname)) return 1;
	}
	return 0;
}
示例#4
0
/* int max_len:  for returned value    */
int
ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data,
    int max_len)
{
	int ret = -1, n;
	ASN1_INTEGER *ai = NULL;
	ASN1_OCTET_STRING *os = NULL;
	const unsigned char *p;
	long length;
	ASN1_const_CTX c;

	if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) {
		goto err;
	}
	p = ASN1_STRING_data(a->value.sequence);
	length = ASN1_STRING_length(a->value.sequence);

	c.pp = &p;
	c.p = p;
	c.max = p + length;
	c.error = ASN1_R_DATA_IS_WRONG;

	M_ASN1_D2I_start_sequence();
	c.q = c.p;
	if ((ai = d2i_ASN1_INTEGER(NULL, &c.p, c.slen)) == NULL)
		goto err;
	c.slen -= (c.p - c.q);
	c.q = c.p;
	if ((os = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL)
		goto err;
	c.slen -= (c.p - c.q);
	if (!M_ASN1_D2I_end_sequence())
		goto err;

	if (num != NULL)
		*num = ASN1_INTEGER_get(ai);

	ret = ASN1_STRING_length(os);
	if (max_len > ret)
		n = ret;
	else
		n = max_len;

	if (data != NULL)
		memcpy(data, ASN1_STRING_data(os), n);
	if (0) {
err:
		ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING,
		    ASN1_R_DATA_IS_WRONG);
	}
	M_ASN1_OCTET_STRING_free(os);
	M_ASN1_INTEGER_free(ai);
	return (ret);
}
示例#5
0
文件: https.c 项目: dhawes/libduo
/* Server certificate name check, logic adapted from libcurl */
static int
_SSL_check_server_cert(SSL *ssl, const char *hostname)
{
        X509 *cert;
        X509_NAME *subject;
        const GENERAL_NAME *altname;
        STACK_OF(GENERAL_NAME) *altnames;
        ASN1_STRING *tmp;
        int i, n, match = -1;
        const char *p;
        
        if (SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE ||
            (cert = SSL_get_peer_certificate(ssl)) == NULL) {
                return (1);
        }
        /* Check subjectAltName */
        if ((altnames = X509_get_ext_d2i(cert, NID_subject_alt_name,
                    NULL, NULL)) != NULL) {
                n = sk_GENERAL_NAME_num(altnames);
                
                for (i = 0; i < n && match != 1; i++) {
                        altname = sk_GENERAL_NAME_value(altnames, i);
                        p = (char *)ASN1_STRING_data(altname->d.ia5);
                        if (altname->type == GEN_DNS) {
                                match = (ASN1_STRING_length(altname->d.ia5) ==
                                    strlen(p) && match_pattern(hostname, p));
                        }
                }
                GENERAL_NAMES_free(altnames);
        }
        /* No subjectAltName, try CN */
        if (match == -1 &&
            (subject = X509_get_subject_name(cert)) != NULL) {
                for (i = -1; (n = X509_NAME_get_index_by_NID(subject,
                            NID_commonName, i)) >= 0; ) {
                        i = n;
                }
                if (i >= 0) {
                        if ((tmp = X509_NAME_ENTRY_get_data(
                                   X509_NAME_get_entry(subject, i))) != NULL &&
                            ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) {
                                p = (char *)ASN1_STRING_data(tmp);
                                match = (ASN1_STRING_length(tmp) ==
                                    strlen(p) && match_pattern(hostname, p));
                        }
                }
        }
        X509_free(cert);
        
        return (match > 0);
}
示例#6
0
int subjectaltnameaddr(X509 *cert, int family, const struct in6_addr *addr) {
    int loc, i, l, n, r = 0;
    char *v;
    X509_EXTENSION *ex;
    STACK_OF(GENERAL_NAME) *alt;
    GENERAL_NAME *gn;

    debug(DBG_DBG, "subjectaltnameaddr");

    loc = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
    if (loc < 0)
	return r;

    ex = X509_get_ext(cert, loc);
    alt = X509V3_EXT_d2i(ex);
    if (!alt)
	return r;

    n = sk_GENERAL_NAME_num(alt);
    for (i = 0; i < n; i++) {
	gn = sk_GENERAL_NAME_value(alt, i);
	if (gn->type != GEN_IPADD)
	    continue;
	r = -1;
	v = (char *)ASN1_STRING_data(gn->d.ia5);
	l = ASN1_STRING_length(gn->d.ia5);
	if (((family == AF_INET && l == sizeof(struct in_addr)) || (family == AF_INET6 && l == sizeof(struct in6_addr)))
	    && !memcmp(v, &addr, l)) {
	    r = 1;
	    break;
	}
    }
    GENERAL_NAMES_free(alt);
    return r;
}
示例#7
0
static PyObject *
get_subject (certificate_x509 *self, PyObject *args)
{
	if (!PyArg_ParseTuple (args, "")) {
		return NULL;
	}

	X509_NAME *name = X509_get_subject_name (self->x509);
	int entries = X509_NAME_entry_count (name);
	int i;

	PyObject *dict = PyDict_New ();
	for (i = 0; i < entries; i++) {
		X509_NAME_ENTRY *entry = X509_NAME_get_entry (name, i);
		ASN1_OBJECT *obj = X509_NAME_ENTRY_get_object (entry);
		ASN1_STRING *data = X509_NAME_ENTRY_get_data (entry);

		PyObject *key =
			PyString_FromString (OBJ_nid2sn (OBJ_obj2nid (obj)));
		PyObject *value = PyString_FromString ((const char *)
						       ASN1_STRING_data (data));
		PyDict_SetItem (dict, key, value);

		Py_DECREF (key);
		Py_DECREF (value);
	}

	return dict;
}
static HostnameValidationResult validate_name(const char *hostname, ASN1_STRING *certname_asn1) {
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) && !defined(LIBRESSL_VERSION_NUMBER)
	char *certname_s = (char *) ASN1_STRING_get0_data(certname_asn1);
#else
	char *certname_s = (char *) ASN1_STRING_data(certname_asn1);
#endif
	int certname_len = ASN1_STRING_length(certname_asn1), hostname_len = strlen(hostname);

	// Make sure there isn't an embedded NUL character in the DNS name
	if (has_nul(certname_s, certname_len)) {
		return MalformedCertificate;
	}
	// remove last '.' from hostname
	if (hostname_len != 0 && hostname[hostname_len - 1] == '.')
		--hostname_len;
	// skip the first segment if wildcard
	if (certname_len > 2 && certname_s[0] == '*' && certname_s[1] == '.') {
		if (hostname_len != 0) {
			do {
				--hostname_len;
				if (*hostname++ == '.')
					break;
			} while (hostname_len != 0);
		}
		certname_s += 2;
		certname_len -= 2;
	}
	// Compare expected hostname with the DNS name
	if (certname_len != hostname_len) {
		return MatchNotFound;
	}
	return memeq_ncase(hostname, certname_s, hostname_len) ? MatchFound : MatchNotFound;
}
示例#9
0
/* Convert an ASN1 string which may not be null terminated into a
 * standard null terminated string. Also check for embedded null
 * characters.
 */
char *asn1_to_cstr(ASN1_STRING *astr)
{
    unsigned int astr_len = 0;
    char *tmp = NULL;
    char *cstr = NULL;

    if (!(astr_len = (unsigned int) ASN1_STRING_length(astr))) {
        return NULL;
    }

    if (!(tmp = (char *)ASN1_STRING_data(astr))) {
        return NULL;
    }

    /* Verify that the string does not contain embedded null characters.
     */
    if (memchr(tmp, '\0', astr_len)) {
        return NULL;
    }

    if ((cstr = (char *) malloc(astr_len + 1)) == NULL) {
        return NULL;
    }

    memcpy(cstr, tmp, astr_len);
    cstr[astr_len] = '\0';

    return cstr;
}
示例#10
0
TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX (TS_REQ * req, TS_VERIFY_CTX * ctx)
{
    TS_VERIFY_CTX *ret = ctx;

    ASN1_OBJECT *policy;

    TS_MSG_IMPRINT *imprint;

    X509_ALGOR *md_alg;

    ASN1_OCTET_STRING *msg;

    const ASN1_INTEGER *nonce;

    OPENSSL_assert (req != NULL);
    if (ret)
        TS_VERIFY_CTX_cleanup (ret);
    else if (!(ret = TS_VERIFY_CTX_new ()))
        return NULL;

    /* Setting flags. */
    ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE);

    /* Setting policy. */
    if ((policy = TS_REQ_get_policy_id (req)) != NULL)
    {
        if (!(ret->policy = OBJ_dup (policy)))
            goto err;
    }
    else
        ret->flags &= ~TS_VFY_POLICY;

    /* Setting md_alg, imprint and imprint_len. */
    imprint = TS_REQ_get_msg_imprint (req);
    md_alg = TS_MSG_IMPRINT_get_algo (imprint);
    if (!(ret->md_alg = X509_ALGOR_dup (md_alg)))
        goto err;
    msg = TS_MSG_IMPRINT_get_msg (imprint);
    ret->imprint_len = ASN1_STRING_length (msg);
    if (!(ret->imprint = OPENSSL_malloc (ret->imprint_len)))
        goto err;
    memcpy (ret->imprint, ASN1_STRING_data (msg), ret->imprint_len);

    /* Setting nonce. */
    if ((nonce = TS_REQ_get_nonce (req)) != NULL)
    {
        if (!(ret->nonce = ASN1_INTEGER_dup (nonce)))
            goto err;
    }
    else
        ret->flags &= ~TS_VFY_NONCE;

    return ret;
  err:
    if (ctx)
        TS_VERIFY_CTX_cleanup (ctx);
    else
        TS_VERIFY_CTX_free (ret);
    return NULL;
}
示例#11
0
static char *
get_peer_common_name(const struct ssl_stream *sslv)
{
    X509 *peer_cert = SSL_get_peer_certificate(sslv->ssl);
    if (!peer_cert) {
        return NULL;
    }

    int cn_index = X509_NAME_get_index_by_NID(X509_get_subject_name(peer_cert),
                                              NID_commonName, -1);
    if (cn_index < 0) {
        return NULL;
    }

    X509_NAME_ENTRY *cn_entry = X509_NAME_get_entry(
        X509_get_subject_name(peer_cert), cn_index);
    if (!cn_entry) {
        return NULL;
    }

    ASN1_STRING *cn_data = X509_NAME_ENTRY_get_data(cn_entry);
    if (!cn_data) {
        return NULL;
    }

    const char *cn;
#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
    /* ASN1_STRING_data() is deprecated as of OpenSSL version 1.1 */
    cn = (const char *)ASN1_STRING_data(cn_data);
#else
    cn = (const char *)ASN1_STRING_get0_data(cn_data);
 #endif
    return xstrdup(cn);
}
示例#12
0
文件: xattrs.c 项目: Udo/lua-openssl
static X509_ATTRIBUTE* openssl_new_xattribute(lua_State*L, X509_ATTRIBUTE** a, int idx, int utf8)
{
  int arttype;
  size_t len;
  int nid;
  const char* data;

  lua_getfield(L, idx, "object");
  nid = openssl_get_nid(L, -1);
  lua_pop(L, 1);

  lua_getfield(L, idx, "type");
  arttype = openssl_get_asn1type(L, -1);
  lua_pop(L, 1);

  lua_getfield(L, idx, "value");
  if(lua_isuserdata(L, -1))
  {
    ASN1_STRING* value = CHECK_OBJECT(-1, ASN1_STRING, "openssl.asn1_string");
    data = ASN1_STRING_data(value);
    len  = ASN1_STRING_length(value);
  }else
    data = luaL_checklstring(L, idx, &len);
  lua_pop(L, 1);

  return X509_ATTRIBUTE_create_by_NID(a, nid, arttype, data, len);
}
示例#13
0
文件: dh_ameth.c 项目: Orav/kbengine
static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
                              X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
{
    ASN1_OBJECT *aoid;
    int atype;
    void *aval;
    ASN1_INTEGER *public_key = NULL;
    int rv = 0;
    EVP_PKEY *pkpeer = NULL, *pk = NULL;
    DH *dhpeer = NULL;
    const unsigned char *p;
    int plen;

    X509_ALGOR_get0(&aoid, &atype, &aval, alg);
    if (OBJ_obj2nid(aoid) != NID_dhpublicnumber)
        goto err;
    /* Only absent parameters allowed in RFC XXXX */
    if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL)
        goto err;

    pk = EVP_PKEY_CTX_get0_pkey(pctx);
    if (!pk)
        goto err;
    if (pk->type != EVP_PKEY_DHX)
        goto err;
    /* Get parameters from parent key */
    dhpeer = DHparams_dup(pk->pkey.dh);
    /* We have parameters now set public key */
    plen = ASN1_STRING_length(pubkey);
    p = ASN1_STRING_data(pubkey);
    if (!p || !plen)
        goto err;

    if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, plen))) {
        DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR);
        goto err;
    }

    /* We have parameters now set public key */
    if (!(dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) {
        DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR);
        goto err;
    }

    pkpeer = EVP_PKEY_new();
    if (!pkpeer)
        goto err;
    EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer);
    dhpeer = NULL;
    if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
        rv = 1;
 err:
    if (public_key)
        ASN1_INTEGER_free(public_key);
    if (pkpeer)
        EVP_PKEY_free(pkpeer);
    if (dhpeer)
        DH_free(dhpeer);
    return rv;
}
示例#14
0
static int matches_common_name(const char *hostname, const X509 *server_cert)
{
    int common_name_loc = -1;
    X509_NAME_ENTRY *common_name_entry = 0;
    ASN1_STRING *common_name_asn1 = 0;
    char *common_name_str = 0;

    common_name_loc = X509_NAME_get_index_by_NID(X509_get_subject_name(
                          (X509 *) server_cert),
                      NID_commonName, -1);
    if (common_name_loc < 0) {
        return Error;
    }
    common_name_entry = X509_NAME_get_entry(
                            X509_get_subject_name(
                                (X509 *) server_cert),
                            common_name_loc);
    if (!common_name_entry) {
        return Error;
    }
    common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry);
    if (!common_name_asn1) {
        return Error;
    }
    common_name_str = (char *) ASN1_STRING_data(common_name_asn1);
    if (ASN1_STRING_length(common_name_asn1) != strlen(common_name_str)) {
        return MalformedCertificate;
    }
    if (!strcasecmp(hostname, common_name_str)) {
        return MatchFound;
    }
    else {
        return MatchNotFound;
    }
}
示例#15
0
const char *tls_dns_name(const GENERAL_NAME * gn,
			         const TLS_SESS_STATE *TLScontext)
{
    const char *myname = "tls_dns_name";
    char   *cp;
    const char *dnsname;
    int     len;

    /*
     * Peername checks are security sensitive, carefully scrutinize the
     * input!
     */
    if (gn->type != GEN_DNS)
	msg_panic("%s: Non DNS input argument", myname);

    /*
     * We expect the OpenSSL library to construct GEN_DNS extesion objects as
     * ASN1_IA5STRING values. Check we got the right union member.
     */
    if (ASN1_STRING_type(gn->d.ia5) != V_ASN1_IA5STRING) {
	msg_warn("%s: %s: invalid ASN1 value type in subjectAltName",
		 myname, TLScontext->namaddr);
	return (0);
    }

    /*
     * Safe to treat as an ASCII string possibly holding a DNS name
     */
    dnsname = (char *) ASN1_STRING_data(gn->d.ia5);
    len = ASN1_STRING_length(gn->d.ia5);
    TRIM0(dnsname, len);

    /*
     * Per Dr. Steven Henson of the OpenSSL development team, ASN1_IA5STRING
     * values can have internal ASCII NUL values in this context because
     * their length is taken from the decoded ASN1 buffer, a trailing NUL is
     * always appended to make sure that the string is terminated, but the
     * ASN.1 length may differ from strlen().
     */
    if (len != strlen(dnsname)) {
	msg_warn("%s: %s: internal NUL in subjectAltName",
		 myname, TLScontext->namaddr);
	return 0;
    }

    /*
     * XXX: Should we be more strict and call valid_hostname()? So long as
     * the name is safe to handle, if it is not a valid hostname, it will not
     * compare equal to the expected peername, so being more strict than
     * "printable" is likely excessive...
     */
    if (*dnsname && !allprint(dnsname)) {
	cp = mystrdup(dnsname);
	msg_warn("%s: %s: non-printable characters in subjectAltName: %.100s",
		 myname, TLScontext->namaddr, printable(cp, '?'));
	myfree(cp);
	return 0;
    }
    return (dnsname);
}
示例#16
0
static int pub_encode_gost94(X509_PUBKEY *pub,const EVP_PKEY *pk)
	{
	ASN1_OBJECT *algobj = NULL;
	ASN1_OCTET_STRING *octet = NULL;
	void *pval = NULL;
	unsigned char *buf=NULL,*databuf,*sptr;
	int i,j,data_len,ret=0;

	int ptype = V_ASN1_UNDEF;
	DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk);
	algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
	if (pk->save_parameters) 
		{
		ASN1_STRING *params = encode_gost_algor_params(pk);
		pval = params;
		ptype = V_ASN1_SEQUENCE;
		}	
	data_len = BN_num_bytes(dsa->pub_key);
	databuf = OPENSSL_malloc(data_len);
	BN_bn2bin(dsa->pub_key,databuf);
	octet = ASN1_OCTET_STRING_new();
	ASN1_STRING_set(octet,NULL,data_len);
	sptr = ASN1_STRING_data(octet);
	for (i=0,j=data_len-1; i< data_len;i++,j--)
		{
		sptr[i]=databuf[j];
		}
	OPENSSL_free(databuf);
	ret = i2d_ASN1_OCTET_STRING(octet,&buf);
	ASN1_BIT_STRING_free(octet);
	if (ret <0)  return 0;
	return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
	}
示例#17
0
std::string genCommonName(X509* cert) {
  if (cert == nullptr) {
    return "";
  }

  auto subject_name = X509_get_subject_name(cert);
  if (subject_name == nullptr) {
    return "";
  }

  auto nid = OBJ_txt2nid("CN");
  auto index = X509_NAME_get_index_by_NID(subject_name, nid, -1);
  if (index == -1) {
    return "";
  }

  auto commonNameEntry = X509_NAME_get_entry(subject_name, index);
  if (commonNameEntry == nullptr) {
    return "";
  }

  auto commonNameData = X509_NAME_ENTRY_get_data(commonNameEntry);
  auto data = ASN1_STRING_data(commonNameData);
  return std::string(reinterpret_cast<char*>(data));
}
示例#18
0
文件: tls.c 项目: hutchinson/freetds
static int
check_alt_names(X509 *cert, const char *hostname)
{
	STACK_OF(GENERAL_NAME) *alt_names;
	int i, num;
	int ret = 1;
	union {
		struct in_addr v4;
		struct in6_addr v6;
	} ip;
	unsigned ip_size = 0;

	/* check whether @hostname is an ip address */
	if (strchr(hostname, ':') != NULL) {
		ip_size = 16;
		ret = inet_pton(AF_INET6, hostname, &ip.v6);
	} else {
		ip_size = 4;
		ret = inet_pton(AF_INET, hostname, &ip.v4);
	}
	if (ret == 0)
		return -1;

	ret = -1;

	alt_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
	if (!alt_names)
		return ret;

	num = sk_GENERAL_NAME_num(alt_names);
	tdsdump_log(TDS_DBG_INFO1, "Alt names number %d\n", num);
	for (i = 0; i < num; ++i) {
		const char *altptr;
		size_t altlen;

		const GENERAL_NAME *name = sk_GENERAL_NAME_value(alt_names, i);
		if (!name)
			continue;

		altptr = (const char *) ASN1_STRING_data(name->d.ia5);
		altlen = (size_t) ASN1_STRING_length(name->d.ia5);

		if (name->type == GEN_DNS && ip_size == 0) {
			ret = 0;
			if (!check_name_match(name->d.dNSName, hostname))
				continue;
		} else if (name->type == GEN_IPADD && ip_size != 0) {
			ret = 0;
			if (altlen != ip_size || memcmp(altptr, &ip, altlen) != 0)
				continue;
		} else {
			continue;
		}

		sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
		return 1;
	}
	sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
	return ret;
}
示例#19
0
std::unique_ptr<std::list<std::string>> SSLUtil::getSubjectAltName(
    const X509* cert) {
#ifdef OPENSSL_GE_101
  auto nameList = folly::make_unique<std::list<std::string>>();
  GENERAL_NAMES* names = (GENERAL_NAMES*)X509_get_ext_d2i(
      (X509*)cert, NID_subject_alt_name, nullptr, nullptr);
  if (names) {
    auto guard = folly::makeGuard([names] { GENERAL_NAMES_free(names); });
    size_t count = sk_GENERAL_NAME_num(names);
    CHECK(count < std::numeric_limits<int>::max());
    for (int i = 0; i < (int)count; ++i) {
      GENERAL_NAME* generalName = sk_GENERAL_NAME_value(names, i);
      if (generalName->type == GEN_DNS) {
        ASN1_STRING* s = generalName->d.dNSName;
        const char* name = (const char*)ASN1_STRING_data(s);
        // I can't find any docs on what a negative return value here
        // would mean, so I'm going to ignore it.
        auto len = ASN1_STRING_length(s);
        DCHECK(len >= 0);
        if (size_t(len) != strlen(name)) {
          // Null byte(s) in the name; return an error rather than depending on
          // the caller to safely handle this case.
          return nullptr;
        }
        nameList->emplace_back(name);
      }
    }
  }
  return nameList;
#else
  return nullptr;
#endif
}
示例#20
0
std::string genCommonName(X509* cert) {
  if (cert == nullptr) {
    return "";
  }

  X509_NAME* subject_name = nullptr;
  OSX_OPENSSL(subject_name = X509_get_subject_name(cert));
  if (subject_name == nullptr) {
    return "";
  }

  int nid = 0;
  OSX_OPENSSL(nid = OBJ_txt2nid("CN"));

  int index = 0;
  OSX_OPENSSL(index = X509_NAME_get_index_by_NID(subject_name, nid, -1));
  if (index == -1) {
    return "";
  }

  X509_NAME_ENTRY* commonNameEntry = nullptr;
  OSX_OPENSSL(commonNameEntry = X509_NAME_get_entry(subject_name, index));
  if (commonNameEntry == nullptr) {
    return "";
  }

  ASN1_STRING* commonNameData = nullptr;
  OSX_OPENSSL(commonNameData = X509_NAME_ENTRY_get_data(commonNameEntry));

  unsigned char* data = nullptr;
  OSX_OPENSSL(data = ASN1_STRING_data(commonNameData));
  return std::string(reinterpret_cast<char*>(data));
}
示例#21
0
/*
 * read an attribute of type octet string
 */
unsigned char	*sigattr_octet(scep_t *scep, char *attrname, int *len) {
	ASN1_OCTET_STRING		*asn1;
	unsigned char			*data = NULL;

	/* get the attribute as an ASN1_OCTET_STRING			*/
	
	asn1 = sigattr_asn1_octet(scep, attrname);
	if (asn1 == NULL)
		return NULL;
	if (debug)
		BIO_printf(bio_err, "%s:%d: got an asn1 string for attribute\n",
			__FILE__ , __LINE__);
	
	/* unpack the ASN1_STRING into a C-String (0-terminated)	*/
	*len = ASN1_STRING_length(asn1);
	data = (unsigned char *)malloc(*len);
	memcpy(data, ASN1_STRING_data(asn1), *len);
	if (debug)
		BIO_printf(bio_err, "%s:%d: allocated %d new bytes for value\n",
			__FILE__, __LINE__, *len);

	/* return the data						*/

	return data;
}
示例#22
0
/* int max_len:  for returned value    */
int ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *a, long *num,
                                  unsigned char *data, int max_len)
{
    asn1_int_oct *atmp = NULL;
    int ret = -1, n;

    if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) {
        goto err;
    }

    atmp = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(asn1_int_oct), a);

    if (atmp == NULL)
        goto err;

    if (num != NULL)
        *num = atmp->num;

    ret = ASN1_STRING_length(atmp->oct);
    if (max_len > ret)
        n = ret;
    else
        n = max_len;

    if (data != NULL)
        memcpy(data, ASN1_STRING_data(atmp->oct), n);
    if (ret == -1) {
 err:
        ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
    }
    M_ASN1_free_of(atmp, asn1_int_oct);
    return ret;
}
示例#23
0
文件: x509.c 项目: horazont/luasec
/**
 * Push the ASN1 string on the stack.
 */
static void push_asn1_string(lua_State* L, ASN1_STRING *string)
{
  if (string)
    lua_pushlstring(L, (char*)ASN1_STRING_data(string),
                       ASN1_STRING_length(string));
  else
    lua_pushnil(L);
}
示例#24
0
static size_t
get_extension_by_object (X509 *x509, ASN1_OBJECT *obj, char **output)
{
	int pos = X509_get_ext_by_OBJ (x509, obj, -1);
	if (pos < 0) {
		return 0;
	}
	X509_EXTENSION *ext = X509_get_ext (x509, pos);

	int tag;
	long len;
	int tc;
	const unsigned char *p = ext->value->data;

	ASN1_get_object (&p, &len, &tag, &tc, ext->value->length);

	size_t size;
	switch (tag) {
		case V_ASN1_UTF8STRING:
			{
				ASN1_UTF8STRING *str =
					ASN1_item_unpack (ext->value,
							  ASN1_ITEM_rptr
							  (ASN1_UTF8STRING));
				*output = strndup ((const char *)
						   ASN1_STRING_data (str),
						   str->length);
				size = str->length;
				ASN1_UTF8STRING_free (str);
				return size;
			}
		case V_ASN1_OCTET_STRING:
			{
				ASN1_OCTET_STRING *octstr =
					ASN1_item_unpack (ext->value,
							  ASN1_ITEM_rptr
							  (ASN1_OCTET_STRING));
				*output = malloc (octstr->length);
				memcpy (*output, octstr->data, octstr->length);
				size = octstr->length;
				ASN1_OCTET_STRING_free (octstr);
				return size;
			}
		default:
			{
				BIO *bio = BIO_new (BIO_s_mem ());
				X509V3_EXT_print (bio, ext, 0, 0);

				size_t size = BIO_ctrl_pending (bio);
				char *buf = malloc (sizeof (char) * size);
				BIO_read (bio, buf, size);
				*output = buf;
				BIO_free (bio);
				return size;
			}
	}
}
示例#25
0
文件: ec_ameth.c 项目: 0culus/openssl
static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
				X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
	{
	ASN1_OBJECT *aoid;
	int atype;
	void *aval;
	int rv = 0;
	EVP_PKEY *pkpeer = NULL;
	EC_KEY *ecpeer = NULL;
	const unsigned char *p;
	int plen;
	X509_ALGOR_get0(&aoid, &atype, &aval, alg);
	if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey)
		goto err;
	/* If absent parameters get group from main key */
	if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL)
		{
		const EC_GROUP *grp;
		EVP_PKEY *pk;
		pk = EVP_PKEY_CTX_get0_pkey(pctx);
		if (!pk)
			goto err;
		grp = EC_KEY_get0_group(pk->pkey.ec);
		ecpeer = EC_KEY_new();
		if (!ecpeer)
			goto err;
		if (!EC_KEY_set_group(ecpeer, grp))
			goto err;
		}
	else
		{
		ecpeer = eckey_type2param(atype, aval);
		if (!ecpeer)
			goto err;
		}
	/* We have parameters now set public key */
	plen = ASN1_STRING_length(pubkey);
	p = ASN1_STRING_data(pubkey);
	if (!p || !plen)
		goto err;
	if (!o2i_ECPublicKey(&ecpeer, &p, plen))
		goto err;
	pkpeer = EVP_PKEY_new();
	if (!pkpeer)
		goto err;
	EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer);
	if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
		rv = 1;
	err:
	if (ecpeer)
		EC_KEY_free(ecpeer);
	if (pkpeer)
		EVP_PKEY_free(pkpeer);
	return rv;
	}
示例#26
0
static int pub_encode_gost01(X509_PUBKEY *pub,const EVP_PKEY *pk)
	{
	ASN1_OBJECT *algobj = NULL;
	ASN1_OCTET_STRING *octet = NULL;
	void *pval = NULL;
	unsigned char *buf=NULL,*databuf,*sptr;
	int i,j,data_len,ret=0;
	const EC_POINT *pub_key;
	BIGNUM *X,*Y,*order;
	const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk);
	int ptype = V_ASN1_UNDEF;

	algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk));
	if (pk->save_parameters) 
		{
		ASN1_STRING *params = encode_gost_algor_params(pk);
		pval = params;
		ptype = V_ASN1_SEQUENCE;
		}
	order = BN_new();
	EC_GROUP_get_order(EC_KEY_get0_group(ec),order,NULL);
	pub_key=EC_KEY_get0_public_key(ec);
	if (!pub_key) 
		{
		GOSTerr(GOST_F_PUB_ENCODE_GOST01,
			GOST_R_PUBLIC_KEY_UNDEFINED);
		return 0;
		}	
	X=BN_new();
	Y=BN_new();
	EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec),
		pub_key,X,Y,NULL);
	data_len = 2*BN_num_bytes(order);
	BN_free(order);
	databuf = OPENSSL_malloc(data_len);
	memset(databuf,0,data_len);
	
	store_bignum(X,databuf+data_len/2,data_len/2);
	store_bignum(Y,databuf,data_len/2);

	BN_free(X);
	BN_free(Y);
	octet = ASN1_OCTET_STRING_new();
	ASN1_STRING_set(octet,NULL,data_len);
	sptr=ASN1_STRING_data(octet);
    for (i=0,j=data_len-1;i<data_len;i++,j--) 
		{
        sptr[i]=databuf[j];
		}
    OPENSSL_free(databuf);
	ret = i2d_ASN1_OCTET_STRING(octet,&buf);
	ASN1_BIT_STRING_free(octet);
	if (ret <0)  return 0;
	return X509_PUBKEY_set0_param(pub,algobj,ptype,pval,buf,ret);
	}
示例#27
0
文件: t_x509.c 项目: GH-JY/openssl
int X509_ocspid_print(BIO *bp, X509 *x)
{
    unsigned char *der = NULL;
    unsigned char *dertmp;
    int derlen;
    int i;
    unsigned char SHA1md[SHA_DIGEST_LENGTH];
    ASN1_BIT_STRING *keybstr;
    X509_NAME *subj;

    /*
     * display the hash of the subject as it would appear in OCSP requests
     */
    if (BIO_printf(bp, "        Subject OCSP hash: ") <= 0)
        goto err;
    subj = X509_get_subject_name(x);
    derlen = i2d_X509_NAME(subj, NULL);
    if ((der = dertmp = OPENSSL_malloc(derlen)) == NULL)
        goto err;
    i2d_X509_NAME(subj, &dertmp);

    if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
        goto err;
    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
        if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
            goto err;
    }
    OPENSSL_free(der);
    der = NULL;

    /*
     * display the hash of the public key as it would appear in OCSP requests
     */
    if (BIO_printf(bp, "\n        Public key OCSP hash: ") <= 0)
        goto err;

    keybstr = X509_get0_pubkey_bitstr(x);

    if (keybstr == NULL)
        goto err;

    if (!EVP_Digest(ASN1_STRING_data(keybstr), ASN1_STRING_length(keybstr),
                    SHA1md, NULL, EVP_sha1(), NULL))
        goto err;
    for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
        if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
            goto err;
    }
    BIO_printf(bp, "\n");

    return (1);
 err:
    OPENSSL_free(der);
    return (0);
}
示例#28
0
static char *__apn_cert_entry_value_string_by_nib(X509_NAME *name, const char * const nid_str) {
    int nid = OBJ_txt2nid(nid_str);
    int index = X509_NAME_get_index_by_NID(name, nid, -1);
    if(index != -1) {
        X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, index);
        const unsigned char *entry_value = ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry));
        if(entry_value) {
            return apn_strndup((const char *)entry_value, strlen((const char *)entry_value));
        }
    }
    return NULL;
}
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
				const unsigned char *salt, int saltlen)
	{
	PBEPARAM *pbe=NULL;
	ASN1_STRING *pbe_str=NULL;
	unsigned char *sstr;

	pbe = PBEPARAM_new();
	if (!pbe)
		{
		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	if(iter <= 0)
		iter = PKCS5_DEFAULT_ITER;
	if (!ASN1_INTEGER_set(pbe->iter, iter))
		{
		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	if (!saltlen)
		saltlen = PKCS5_SALT_LEN;
	if (!ASN1_STRING_set(pbe->salt, NULL, saltlen))
		{
		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	sstr = ASN1_STRING_data(pbe->salt);
	if (salt)
		TINYCLR_SSL_MEMCPY(sstr, salt, saltlen);
	else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
		goto err;

	if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str))
		{
		ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	PBEPARAM_free(pbe);
	pbe = NULL;

	if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
		return 1;

err:
	if (pbe != NULL)
		PBEPARAM_free(pbe);
	if (pbe_str != NULL)
		ASN1_STRING_free(pbe_str);
	return 0;
	}
示例#30
0
int subjectaltnameregexp(X509 *cert, int type, const char *exact,  const regex_t *regex) {
    int loc, i, l, n, r = 0;
    char *s, *v;
    X509_EXTENSION *ex;
    STACK_OF(GENERAL_NAME) *alt;
    GENERAL_NAME *gn;

    debug(DBG_DBG, "subjectaltnameregexp");

    loc = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
    if (loc < 0)
	return r;

    ex = X509_get_ext(cert, loc);
    alt = X509V3_EXT_d2i(ex);
    if (!alt)
	return r;

    n = sk_GENERAL_NAME_num(alt);
    for (i = 0; i < n; i++) {
	gn = sk_GENERAL_NAME_value(alt, i);
	if (gn->type != type)
	    continue;
	r = -1;
	v = (char *)ASN1_STRING_data(gn->d.ia5);
	l = ASN1_STRING_length(gn->d.ia5);
	if (l <= 0)
	    continue;
#ifdef DEBUG
	printfchars(NULL, gn->type == GEN_DNS ? "dns" : "uri", NULL, v, l);
#endif
	if (exact) {
	    if (memcmp(v, exact, l))
		continue;
	} else {
	    s = stringcopy((char *)v, l);
	    if (!s) {
		debug(DBG_ERR, "malloc failed");
		continue;
	    }
	    if (regexec(regex, s, 0, NULL, 0)) {
		free(s);
		continue;
	    }
	    free(s);
	}
	r = 1;
	break;
    }
    GENERAL_NAMES_free(alt);
    return r;
}