Beispiel #1
0
static int
check_hostname(X509 *cert, const char *hostname)
{
	int ret, i;
	X509_NAME *subject;
	ASN1_STRING *name;

	/* check by subject */
	ret = check_alt_names(cert, hostname);
	if (ret >= 0)
		return ret;

	/* check by common name (old method) */
	subject= X509_get_subject_name(cert);
	if (!subject)
		return 0;

	i = -1;
	while (X509_NAME_get_index_by_NID(subject, NID_commonName, i) >=0)
		i = X509_NAME_get_index_by_NID(subject, NID_commonName, i);
	if (i < 0)
		return 0;

	name = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject, i));
	if (!name)
		return 0;

	return check_name_match(name, hostname);
}
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());
			}
		}
	}
}
Beispiel #3
0
int
eventer_ssl_get_local_commonname(eventer_ssl_ctx_t *ctx, char *buff, int len) {
  char *out = NULL;
  X509_NAME *name;
  X509 *cert = SSL_get_certificate(ctx->ssl);
  if(cert == NULL) return -1;
  name = X509_get_subject_name(cert);
  if(name) {
    int pos;
    if(-1 != (pos = X509_NAME_get_index_by_NID(name, NID_commonName, -1))) {
      X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, pos);
      if(entry) {
        ASN1_STRING *entryData = X509_NAME_ENTRY_get_data( entry );
        unsigned char *utf8;
        int length = ASN1_STRING_to_UTF8( &utf8, entryData );
        strlcpy(buff, (const char *)utf8, MIN(length+1,len));
        out = buff;
        OPENSSL_free( utf8 );
      }
    }
  }
  X509_free(cert);
  if(out) return strlen(out);
  return -1;
}
Beispiel #4
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;
    }
}
Beispiel #5
0
static inline int tls_check_host(X509 *cert, const char *hostname)
{
	char common_name[256] = "";
	X509_NAME *xname = X509_get_subject_name(cert);
	X509_NAME_ENTRY *xentry;
	ASN1_STRING *sdata;
	int i, j;
	int ret;

	ret = X509_NAME_get_text_by_NID(xname, NID_commonName, common_name, sizeof(common_name));
	if (ret < 1 || (size_t)ret >= (sizeof(common_name)-1))
		return SHOUTERR_TLSBADCERT;

	if (!tls_check_pattern(hostname, common_name))
		return SHOUTERR_TLSBADCERT;

	/* check for inlined \0, see https://www.blackhat.com/html/bh-usa-09/bh-usa-09-archives.html#Marlinspike */
	for (i = -1; ; i = j) {
		j = X509_NAME_get_index_by_NID(xname, NID_commonName, i);
		if (j == -1)
			break;
	}

	xentry = X509_NAME_get_entry(xname, i);
	sdata = X509_NAME_ENTRY_get_data(xentry);

	if ((size_t)ASN1_STRING_length(sdata) != strlen(common_name))
		return SHOUTERR_TLSBADCERT;

	return SHOUTERR_SUCCESS;
}
Beispiel #6
0
char* crypto_cert_subject_common_name(X509* xcert, int* length)
{
	int index;
	uint8* common_name;
	X509_NAME* subject_name;
	X509_NAME_ENTRY* entry;
	ASN1_STRING* entry_data;

	subject_name = X509_get_subject_name(xcert);

	if (subject_name == NULL)
		return NULL;

	index = X509_NAME_get_index_by_NID(subject_name, NID_commonName, -1);

	if (index < 0)
		return NULL;

	entry = X509_NAME_get_entry(subject_name, index);

	if (entry == NULL)
		return NULL;

	entry_data = X509_NAME_ENTRY_get_data(entry);

	if (entry_data == NULL)
		return NULL;

	*length = ASN1_STRING_to_UTF8(&common_name, entry_data);

	if (*length < 0)
		return NULL;

	return (char*) common_name;
}
Beispiel #7
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);
}
Beispiel #8
0
/**
 * Converts individual X.509 subject entry to string.
 *
 * @param ln Long name of the requested entry (see openssl/objects.h)
 * @return subject name entry converted to string.
 * @throws IOException exception is throws if the conversion failed.
 */
std::string digidoc::X509Cert::getSubjectInfo(const std::string& ln) const throw(IOException)
{
    X509_NAME* name = X509_get_subject_name(cert);
    if(name == NULL)
    {
       THROW_IOEXCEPTION("Failed to convert X.509 certificate subject: %s", ERR_reason_error_string(ERR_get_error()));
    }
    int idx = X509_NAME_get_index_by_NID(name, OBJ_ln2nid(ln.c_str()), -1);
    if(idx < 0)
    {
       THROW_IOEXCEPTION("Failed to retrieve X.509 certificate info: field '%s' not found", ln.c_str());
    }
    X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, idx);
    if(!entry)
    {
       THROW_IOEXCEPTION("Failed to convert X.509 certificate field: %s", ERR_reason_error_string(ERR_get_error()));
    }
    ASN1_STRING *asnstr = X509_NAME_ENTRY_get_data(entry);

    unsigned char *data = NULL;
    int len = ASN1_STRING_to_UTF8(&data, asnstr);
    if(len < 0)
    {
       THROW_IOEXCEPTION("Failed to convert X.509 certificate field: %s", ERR_reason_error_string(ERR_get_error()));
    }
    std::string result(reinterpret_cast<const char *>(data));
    OPENSSL_free(data);

    return result;
}
Beispiel #9
0
static int get_comp(str* res, int local, int issuer, int nid, sip_msg_t* msg)
{
	static char buf[1024];
	X509* cert;
	struct tcp_connection* c;
	X509_NAME* name;
	X509_NAME_ENTRY* e;
	ASN1_STRING* asn1;
	int index, text_len;
	char* elem;
	unsigned char* text_s;
	       
	text_s = 0;

	if (get_cert(&cert, &c, msg, local) < 0) return -1;

	name = issuer ? X509_get_issuer_name(cert) : X509_get_subject_name(cert);
	if (!name) {
		ERR("Cannot extract subject or issuer name from peer certificate\n");
		goto err;
	}

	index = X509_NAME_get_index_by_NID(name, nid, -1);
	if (index == -1) {
		switch(nid) {
		case NID_commonName:             elem = "CommonName";              break;
		case NID_organizationName:       elem = "OrganizationName";        break;
		case NID_organizationalUnitName: elem = "OrganizationalUnitUname"; break;
		case NID_countryName:            elem = "CountryName";             break;
		case NID_stateOrProvinceName:    elem = "StateOrProvinceName";     break;
		case NID_localityName:           elem = "LocalityName";            break;
		case NID_userId:                 elem = "UserID";                  break;
		default:                         elem = "Unknown";                 break;
		}
		DBG("Element %s not found in certificate subject/issuer\n", elem);
		goto err;
	}

	e = X509_NAME_get_entry(name, index);
	asn1 = X509_NAME_ENTRY_get_data(e);
	text_len = ASN1_STRING_to_UTF8(&text_s, asn1);
	if (text_len < 0 || text_len >= 1024) {
		ERR("Error converting ASN1 string\n");
		goto err;
	}
	memcpy(buf, text_s, text_len);
	res->s = buf;
	res->len = text_len;

	OPENSSL_free(text_s);
	if (!local) X509_free(cert);
	tcpconn_put(c);
	return 0;

 err:
	if (text_s) OPENSSL_free(text_s);
	if (!local) X509_free(cert);
	tcpconn_put(c);
	return -1;
}
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));
}
/*
 * Returns specified field of specified X509_NAME structure
 *
 * Common part of ssl_client_dn and ssl_issuer_dn functions.
 *
 * Parameter: X509_NAME *name - either subject or issuer of certificate
 * Parameter: text fieldName  - field name string like 'CN' or commonName
 *			  to be looked up in the OpenSSL ASN1 OID database
 *
 * Returns result of ASN1_STRING_to_text applied to appropriate
 * part of name
 */
Datum
X509_NAME_field_to_text(X509_NAME *name, text *fieldName)
{
	char	   *sp;
	char	   *string_fieldname;
	char	   *dp;
	size_t		name_len = VARSIZE(fieldName) - VARHDRSZ;
	int			nid,
				index,
				i;
	ASN1_STRING *data;

	string_fieldname = palloc(name_len + 1);
	sp = VARDATA(fieldName);
	dp = string_fieldname;
	for (i = 0; i < name_len; i++)
		*dp++ = *sp++;
	*dp = '\0';
	nid = OBJ_txt2nid(string_fieldname);
	if (nid == NID_undef)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("invalid X.509 field name: \"%s\"",
						string_fieldname)));
	pfree(string_fieldname);
	index = X509_NAME_get_index_by_NID(name, nid, -1);
	if (index < 0)
		return (Datum) 0;
	data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, index));
	return ASN1_STRING_to_text(data);
}
Beispiel #12
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));
}
Beispiel #13
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;
}
static int
amqp_ssl_socket_verify_hostname(void *base, const char *host)
{
  struct amqp_ssl_socket_t *self = (struct amqp_ssl_socket_t *)base;
  unsigned char *utf8_value = NULL, *cp, ch;
  int pos, utf8_length, status = 0;
  ASN1_STRING *entry_string;
  X509_NAME_ENTRY *entry;
  X509_NAME *name;
  X509 *peer;
  peer = SSL_get_peer_certificate(self->ssl);
  if (!peer) {
    goto error;
  }
  name = X509_get_subject_name(peer);
  if (!name) {
    goto error;
  }
  pos = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
  if (0 > pos) {
    goto error;
  }
  entry = X509_NAME_get_entry(name, pos);
  if (!entry) {
    goto error;
  }
  entry_string = X509_NAME_ENTRY_get_data(entry);
  if (!entry_string) {
    goto error;
  }
  utf8_length = ASN1_STRING_to_UTF8(&utf8_value, entry_string);
  if (0 > utf8_length) {
    goto error;
  }
  while (utf8_length > 0 && utf8_value[utf8_length - 1] == 0) {
    --utf8_length;
  }
  if (utf8_length >= 256) {
    goto error;
  }
  if ((size_t)utf8_length != strlen((char *)utf8_value)) {
    goto error;
  }
  for (cp = utf8_value; (ch = *cp) != '\0'; ++cp) {
    if (isascii(ch) && !isprint(ch)) {
      goto error;
    }
  }
  if (!amqp_hostcheck((char *)utf8_value, host)) {
    goto error;
  }
exit:
  OPENSSL_free(utf8_value);
  return status;
error:
  status = -1;
  goto exit;
}
Beispiel #15
0
/* check the identity in a certificate against a hostname */
RD_BOOL
crypto_cert_verify_peer_identity(CryptoCert cert, const char * peer)
{
	X509_NAME *subject_name = NULL;
	X509_NAME_ENTRY *entry = NULL;
	ASN1_STRING *asn1str = NULL;
	//GENERAL_NAMES *subjectAltNames = NULL;
	unsigned char *ustr = NULL;
	char *str = NULL;
	int i, len;

#if 0
	/* Check cert for subjectAltName extensions */
	/* things to check: ipv4/ipv6 address, hostname in normal form and in DC= form */
	i = -1;
	for (;;)
	{
		subjectAltNames = X509_get_ext_d2i(cert->px509, NID_subject_alt_name, NULL, NULL);
		if (ext == NULL)
			break;
	}n

	/* Check against ip address of server */
#endif
	/* Check commonName */
	subject_name = X509_get_subject_name(cert->px509);
	if (!subject_name)
	{
		printf("crypto_cert_verify_peer_identity: failed to get subject name\n");
		goto exit;
	}

	/* try to find a common name that matches the peer hostname */
	/* TODO: cn migth also be in DC=www,DC=redhat,DC=com format? */
	i = -1;
	for (;;)
	{
		entry = NULL;
		i = X509_NAME_get_index_by_NID(subject_name, NID_commonName, i);
		if (i == -1)
			break;
		entry = X509_NAME_get_entry(subject_name, i);
		asn1str = X509_NAME_ENTRY_get_data(entry);
		len = ASN1_STRING_to_UTF8(&ustr, asn1str);
		str = (char *)ustr;
		if (strcmp(str, peer) == 0)
			break;	/* found a match */
	}

	if (!entry)
	{
		printf("crypto_cert_verify_peer_identity: certificate belongs to %s, "
			"but connection is to %s\n", str ? str : "unknown id", peer);
		return False;
	}
exit:
	return True;
}
Beispiel #16
0
void
x509_setenv_track (const struct x509_track *xt, struct env_set *es, const int depth, X509 *x509)
{
  X509_NAME *x509_name = X509_get_subject_name (x509);
  const char nullc = '\0';
  int i;

  while (xt)
    {
      if (depth == 0 || (xt->flags & XT_FULL_CHAIN))
	{
	  i = X509_NAME_get_index_by_NID(x509_name, xt->nid, -1);
	  if (i >= 0)
	    {
	      X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509_name, i);
	      if (ent)
		{
		  ASN1_STRING *val = X509_NAME_ENTRY_get_data (ent);
		  unsigned char *buf;
		  buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
		  if (ASN1_STRING_to_UTF8 (&buf, val) > 0)
		    {
		      do_setenv_x509(es, xt->name, (char *)buf, depth);
		      OPENSSL_free (buf);
		    }
		}
	    }
	  else
	    {
	      i = X509_get_ext_by_NID(x509, xt->nid, -1);
	      if (i >= 0)
		{
		  X509_EXTENSION *ext = X509_get_ext(x509, i);
		  if (ext)
		    {
		      BIO *bio = BIO_new(BIO_s_mem());
		      if (bio)
			{
			  if (X509V3_EXT_print(bio, ext, 0, 0))
			    {
			      if (BIO_write(bio, &nullc, 1) == 1)
				{
				  char *str;
				  BIO_get_mem_data(bio, &str);
				  do_setenv_x509(es, xt->name, str, depth);
				}
			    }
			  BIO_free(bio);
			}
		    }
		}
	    }
	}
      xt = xt->next;
    }
}
Beispiel #17
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;
}
Beispiel #18
0
void genCommonName(X509* cert,
                   std::string& subject,
                   std::string& common_name,
                   std::string& issuer) {
  if (cert == nullptr) {
    return;
  }

  {
    X509_NAME* issuerName = X509_get_issuer_name(cert);
    if (issuerName != nullptr) {
      // Generate the string representation of the issuer.
      char* issuerBytes = X509_NAME_oneline(issuerName, nullptr, 0);
      if (issuerBytes != nullptr) {
        issuer = std::string(issuerBytes);
        OPENSSL_free(issuerBytes);
      }
    }
  }

  X509_NAME* subjectName = X509_get_subject_name(cert);
  if (subjectName == nullptr) {
    return;
  }

  {
    // Generate the string representation of the subject.
    char* subjectBytes = X509_NAME_oneline(subjectName, nullptr, 0);
    if (subjectBytes != nullptr) {
      subject = std::string(subjectBytes);
      OPENSSL_free(subjectBytes);
    }
  }

  int nid = OBJ_txt2nid("CN");

  int index = X509_NAME_get_index_by_NID(subjectName, nid, -1);
  if (index == -1) {
    return;
  }

  X509_NAME_ENTRY* commonNameEntry = X509_NAME_get_entry(subjectName, index);
  if (commonNameEntry == nullptr) {
    return;
  }

  ASN1_STRING* commonNameData = X509_NAME_ENTRY_get_data(commonNameEntry);

  unsigned char* data = ASN1_STRING_data(commonNameData);
  common_name = std::string(reinterpret_cast<char*>(data));
}
Beispiel #19
0
/* 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);
}
std::string Certificate::GetCommonName() const
{
	if(!ssl_cert)
		return "";

	X509_NAME *subject;
	int pos;
	X509_NAME_ENTRY *entry;
	ASN1_STRING *entry_str;
	int len;
	unsigned char *utf;
	std::string output;

	subject = X509_get_subject_name(ssl_cert);
	pos = X509_NAME_get_index_by_NID(subject, NID_commonName, -1);

	if (pos < 0)
		return "";

	if (X509_NAME_get_index_by_NID(subject, NID_commonName, pos) >= 0)
		return "";

	if ((entry = X509_NAME_get_entry(subject, pos)) == 0)
		throw BadCertificate("Unable to get common name");

	if ((entry_str = X509_NAME_ENTRY_get_data(entry)) == 0)
		throw BadCertificate("Unable to get common name");

	/* Canonicalize to UTF-8 and validate */
	len = ASN1_STRING_to_UTF8(&utf, entry_str);

	output = TypToStr(utf);

	if(utf)
		OPENSSL_free(utf);

	return output;
}
Beispiel #21
0
static char *extract_cn(X509_NAME *subj)
{
	int nid;
	int index;
	ASN1_STRING *d;
	X509_NAME_ENTRY *e;

	nid=OBJ_txt2nid("CN");
	if((index=X509_NAME_get_index_by_NID(subj, nid, -1))<0
	  || !(e=X509_NAME_get_entry(subj, index))
	  || !(d=X509_NAME_ENTRY_get_data(e)))
		return NULL;
	return (char *)ASN1_STRING_data(d);
}
Beispiel #22
0
/* Loop through all the common name entries until we find a match or
 * an error occurs.
 */
int check_subject_cn(X509 *cert, const char *manager)
{
    X509_NAME *name = NULL;
    int result = VERIFY_FALSE;
    int i = 0;

    if ((name = X509_get_subject_name(cert))) {
        while ((i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0 && result == VERIFY_FALSE) {
            X509_NAME_ENTRY *ne = X509_NAME_get_entry(name, i);
            result = check_hostname(X509_NAME_ENTRY_get_data(ne), manager);
        }
    }

    return result;
}
Beispiel #23
0
const char* pn_ssl_get_remote_subject_subfield(pn_ssl_t *ssl0, pn_ssl_cert_subject_subfield field)
{
    int openssl_field = 0;

    // Assign openssl internal representations of field values to openssl_field
    switch (field) {
        case PN_SSL_CERT_SUBJECT_COUNTRY_NAME :
            openssl_field = NID_countryName;
            break;
        case PN_SSL_CERT_SUBJECT_STATE_OR_PROVINCE :
            openssl_field = NID_stateOrProvinceName;
            break;
        case PN_SSL_CERT_SUBJECT_CITY_OR_LOCALITY :
            openssl_field = NID_localityName;
            break;
        case PN_SSL_CERT_SUBJECT_ORGANIZATION_NAME :
            openssl_field = NID_organizationName;
            break;
        case PN_SSL_CERT_SUBJECT_ORGANIZATION_UNIT :
            openssl_field = NID_organizationalUnitName;
            break;
        case PN_SSL_CERT_SUBJECT_COMMON_NAME :
            openssl_field = NID_commonName;
            break;
        default:
            ssl_log_error("Unknown or unhandled certificate subject subfield %i \n", field);
            return NULL;
    }

    pni_ssl_t *ssl = get_ssl_internal(ssl0);
    X509 *cert = get_peer_certificate(ssl);

    X509_NAME *subject_name = X509_get_subject_name(cert);

    // TODO (gmurthy) - A server side cert subject field can have more than one common name like this - Subject: CN=www.domain1.com, CN=www.domain2.com, see https://bugzilla.mozilla.org/show_bug.cgi?id=380656
    // For now, we will only return the first common name if there is more than one common name in the cert
    int index = X509_NAME_get_index_by_NID(subject_name, openssl_field, -1);

    if (index > -1) {
        X509_NAME_ENTRY *ne = X509_NAME_get_entry(subject_name, index);
        if(ne) {
            ASN1_STRING *name_asn1 = X509_NAME_ENTRY_get_data(ne);
            return (char *) name_asn1->data;
        }
    }

    return NULL;
}
Beispiel #24
0
/* return an array of (RFC 6125 coined) DNS-IDs and CN-IDs in a certificate */
BOOL SSL_X509_getIDs(apr_pool_t *p, X509 *x509, apr_array_header_t **ids)
{
    STACK_OF(GENERAL_NAME) *names;
    BIO *bio;
    X509_NAME *subj;
    char **cpp;
    int i, n;

    if (!x509 || !(*ids = apr_array_make(p, 0, sizeof(char *)))) {
        *ids = NULL;
        return FALSE;
    }

    /* First, the DNS-IDs (dNSName entries in the subjectAltName extension) */
    if ((names = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL)) &&
        (bio = BIO_new(BIO_s_mem()))) {
        GENERAL_NAME *name;

        for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
            name = sk_GENERAL_NAME_value(names, i);
            if (name->type == GEN_DNS) {
                ASN1_STRING_print_ex(bio, name->d.ia5, ASN1_STRFLGS_ESC_CTRL|
                                     ASN1_STRFLGS_UTF8_CONVERT);
                n = BIO_pending(bio);
                if (n > 0) {
                    cpp = (char **)apr_array_push(*ids);
                    *cpp = apr_palloc(p, n+1);
                    n = BIO_read(bio, *cpp, n);
                    (*cpp)[n] = NUL;
                }
            }
        }
        BIO_free(bio);
    }

    if (names)
        sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);

    /* Second, the CN-IDs (commonName attributes in the subject DN) */
    subj = X509_get_subject_name(x509);
    i = -1;
    while ((i = X509_NAME_get_index_by_NID(subj, NID_commonName, i)) != -1) {
        cpp = (char **)apr_array_push(*ids);
        *cpp = SSL_X509_NAME_ENTRY_to_string(p, X509_NAME_get_entry(subj, i));
    }

    return apr_is_empty_array(*ids) ? FALSE : TRUE;
}
Beispiel #25
0
/*
 * 这个类呢,是用来实现和 JACK 实现的那个 AVROUTER 对接的。也就是 JACK 版本的 AV NETWORK SERVICE PROVIDER
 */
void avjackif::set_pki(boost::shared_ptr<RSA> _key, boost::shared_ptr<X509> cert)
{
    _rsa = _key;
	_x509 = cert;

	unsigned char * CN = NULL;

	auto cert_name = X509_get_subject_name(cert.get());
	auto cert_entry = X509_NAME_get_entry(cert_name,
		X509_NAME_get_index_by_NID(cert_name, NID_commonName, 0)
	);
	ASN1_STRING *entryData = X509_NAME_ENTRY_get_data( cert_entry );
	auto strlengh = ASN1_STRING_to_UTF8(&CN, entryData);
	printf("%s\n",CN);
	std::string commonname((char*)CN, strlengh);
	m_local_addr.reset(new proto::avAddress(av_address_from_string(commonname)));
	OPENSSL_free(CN);
}
static const char *get_cname(X509 *cert)
{
	X509_NAME *name;
	X509_NAME_ENTRY *entry;
	ASN1_STRING *str;
	int cn_idx;

	name = X509_get_subject_name(cert);
	if (name == NULL)
		return "";
	cn_idx = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
	if (cn_idx == -1)
		return "";
	entry = X509_NAME_get_entry(name, cn_idx);
	i_assert(entry != NULL);
	str = X509_NAME_ENTRY_get_data(entry);
	i_assert(str != NULL);
	return asn1_string_to_c(str);
}
Beispiel #27
0
static int openssl_xname_get_text(lua_State*L)
{
  X509_NAME* xn = CHECK_OBJECT(1, X509_NAME, "openssl.x509_name");
  int nid = openssl_get_nid(L, 2);
  int lastpos = luaL_optint(L, 3, -1);
  X509_NAME_ENTRY *e;
  ASN1_STRING *s;
  if (nid == NID_undef)
    return 0;

  lastpos = X509_NAME_get_index_by_NID(xn, nid, lastpos);
  if (lastpos == -1)
    return 0;

  e = X509_NAME_get_entry(xn, lastpos);
  s = X509_NAME_ENTRY_get_data(e);
  lua_pushlstring(L, (const char *)ASN1_STRING_data(s), ASN1_STRING_length(s));
  lua_pushinteger(L, lastpos);
  return 2;
};
Beispiel #28
0
/*
 * Extract a field from an X509 subject name.
 *
 * Example:
 *
 * /C=US/ST=CO/L=Denver/O=ORG/CN=First-CN/CN=Test-CA/[email protected]
 *
 * The common name is 'Test-CA'
 *
 * Return true on success, false on error (insufficient buffer size in 'out'
 * to contain result is grounds for error).
 */
static result_t
extract_x509_field_ssl (X509_NAME *x509, const char *field_name, char *out,
    int size)
{
  int lastpos = -1;
  int tmp = -1;
  X509_NAME_ENTRY *x509ne = 0;
  ASN1_STRING *asn1 = 0;
  unsigned char *buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */
  int nid = OBJ_txt2nid((char *)field_name);

  ASSERT (size > 0);
  *out = '\0';
  do {
    lastpos = tmp;
    tmp = X509_NAME_get_index_by_NID(x509, nid, lastpos);
  } while (tmp > -1);

  /* Nothing found */
  if (lastpos == -1)
    return FAILURE;

  x509ne = X509_NAME_get_entry(x509, lastpos);
  if (!x509ne)
    return FAILURE;

  asn1 = X509_NAME_ENTRY_get_data(x509ne);
  if (!asn1)
    return FAILURE;
  tmp = ASN1_STRING_to_UTF8(&buf, asn1);
  if (tmp <= 0)
    return FAILURE;

  strncpynt(out, (char *)buf, size);

  {
    const result_t ret = (strlen ((char *)buf) < size) ? SUCCESS: FAILURE;
    OPENSSL_free (buf);
    return ret;
  }
}
Beispiel #29
0
/* Get the UID field from the certificate subject name.
 * The certificate is looked up using the socket of the connection.
 *
 * Return value: Pointer to the uid string or NULL if not found
 */
char *ssl_getuid(int sock)
{
  int idx;
  X509 *cert;
  X509_NAME *subj;
  ASN1_STRING *name;

  if (!(cert = ssl_getcert(sock)))
    return NULL;
  /* Get the subject name */
  if (!(subj = X509_get_subject_name(cert)))
    return NULL;

  /* Get the first UID */
  idx = X509_NAME_get_index_by_NID(subj, NID_userId, -1);
  if (idx == -1)
    return NULL;
  name = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subj, idx));
  /* Extract the contents, assuming null-terminated ASCII string */
  return (char *) ASN1_STRING_data(name);
}
Beispiel #30
0
bool PeerID::Certificate::checkCommonNames(
	const std::function<bool(char const*, std::size_t)> func) const
{
	X509_NAME* name = X509_get_subject_name(x509_);
	int i = -1;
	ASN1_STRING* commonName = 0;
	while ((i = X509_NAME_get_index_by_NID(name, NID_commonName, i)) >= 0)
	{
		X509_NAME_ENTRY* nameEntry = X509_NAME_get_entry(name, i);
		commonName = X509_NAME_ENTRY_get_data(nameEntry);
		if (commonName && commonName->data && commonName->length)
		{
			const char* host = reinterpret_cast<const char*>(commonName->data);
			std::size_t len = commonName->length;
			if (func(host, len))
				return true;
		}
	}

	return false;
}