Exemplo n.º 1
0
char *nussl_ssl_readable_dname(const nussl_ssl_dname * name)
{
	int n, flag = 0;
	nussl_buffer *dump = nussl_buffer_create();
	const ASN1_OBJECT *const cname = OBJ_nid2obj(NID_commonName),
	    *const email = OBJ_nid2obj(NID_pkcs9_emailAddress);

	for (n = X509_NAME_entry_count(name->dn); n > 0; n--) {
		X509_NAME_ENTRY *ent =
		    X509_NAME_get_entry(name->dn, n - 1);

		/* Skip commonName or emailAddress except if there is no other
		 * attribute in dname. */
		if ((OBJ_cmp(ent->object, cname)
		     && OBJ_cmp(ent->object, email)) || (!flag
							 && n == 1)) {
			if (flag++)
				nussl_buffer_append(dump, ", ", 2);

			if (append_dirstring(dump, ent->value))
				nussl_buffer_czappend(dump, "???");
		}
	}

	return nussl_buffer_finish(dump);
}
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());
			}
		}
	}
}
Exemplo n.º 3
0
int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
	{
	int i,j;
	X509_NAME_ENTRY *na,*nb;

	if (sk_X509_NAME_ENTRY_num(a->entries)
	    != sk_X509_NAME_ENTRY_num(b->entries))
		return sk_X509_NAME_ENTRY_num(a->entries)
		  -sk_X509_NAME_ENTRY_num(b->entries);
	for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
		{
		na=sk_X509_NAME_ENTRY_value(a->entries,i);
		nb=sk_X509_NAME_ENTRY_value(b->entries,i);
		j=na->value->length-nb->value->length;
		if (j) return(j);
		j=memcmp(na->value->data,nb->value->data,
			na->value->length);
		if (j) return(j);
		j=na->set-nb->set;
		if (j) return(j);
		}

	/* We will check the object types after checking the values
	 * since the values will more often be different than the object
	 * types. */
	for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
		{
		na=sk_X509_NAME_ENTRY_value(a->entries,i);
		nb=sk_X509_NAME_ENTRY_value(b->entries,i);
		j=OBJ_cmp(na->object,nb->object);
		if (j) return(j);
		}
	return(0);
	}
Exemplo n.º 4
0
int PKI_OID_cmp( PKI_OID *a, PKI_OID *b ) {

	if ( !a || !b ) {
		return(-1);
	}

	return ( OBJ_cmp ( a, b ));
}
Exemplo n.º 5
0
EXPORT_C int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b)
	{
	int ret;
	ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm);
	if (ret) return ret;
	ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash);
	if (ret) return ret;
	return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash);
	}
Exemplo n.º 6
0
/*
 * X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise.
 */
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
{
    int rv;
    rv = OBJ_cmp(a->algorithm, b->algorithm);
    if (rv)
        return rv;
    if (!a->parameter && !b->parameter)
        return 0;
    return ASN1_TYPE_cmp(a->parameter, b->parameter);
}
Exemplo n.º 7
0
/* Returns 0 if they are equal, != 0 otherwise. */
int
X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
{
	int rv = OBJ_cmp(a->algorithm, b->algorithm);
	if (!rv) {
		if (!a->parameter && !b->parameter)
			rv = 0;
		else
			rv = ASN1_TYPE_cmp(a->parameter, b->parameter);
	}
	return(rv);
}
Exemplo n.º 8
0
/* Returns 0 if they are equal, != 0 otherwise. */
int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
{
    int result = -1;

    if (!a || !b)
        return -1;
    /* Check their type first. */
    if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
        return result;
    /* Check the value. */
    result = ASN1_TYPE_cmp(a->value, b->value);
    return result;
}
Exemplo n.º 9
0
int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
	{
	int i,j;
	X509_NAME_ENTRY *na,*nb;

	unsigned long nabit, nbbit;

	j = sk_X509_NAME_ENTRY_num(a->entries)
		  - sk_X509_NAME_ENTRY_num(b->entries);
	if (j)
		return j;
	for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
		{
		na=sk_X509_NAME_ENTRY_value(a->entries,i);
		nb=sk_X509_NAME_ENTRY_value(b->entries,i);
		j=na->value->type-nb->value->type;
		if (j)
			{
			nabit = ASN1_tag2bit(na->value->type);
			nbbit = ASN1_tag2bit(nb->value->type);
			if (!(nabit & STR_TYPE_CMP) ||
				!(nbbit & STR_TYPE_CMP))
				return j;
			if (!asn1_string_memcmp(na->value, nb->value))
				j = 0;
			}
		else if (na->value->type == V_ASN1_PRINTABLESTRING)
			j=nocase_spacenorm_cmp(na->value, nb->value);
		else if (na->value->type == V_ASN1_IA5STRING
			&& OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
			j=nocase_cmp(na->value, nb->value);
		else
			j = asn1_string_memcmp(na->value, nb->value);
		if (j) return(j);
		j=na->set-nb->set;
		if (j) return(j);
		}

	/* We will check the object types after checking the values
	 * since the values will more often be different than the object
	 * types. */
	for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
		{
		na=sk_X509_NAME_ENTRY_value(a->entries,i);
		nb=sk_X509_NAME_ENTRY_value(b->entries,i);
		j=OBJ_cmp(na->object,nb->object);
		if (j) return(j);
		}
	return(0);
	}
Exemplo n.º 10
0
/* Returns 0 if they are equal, != 0 otherwise. */
int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
{
    int result = -1;

    if (!a || !b || a->type != b->type)
        return -1;

    switch (a->type) {
    case V_ASN1_OBJECT:
        result = OBJ_cmp(a->value.object, b->value.object);
        break;
    case V_ASN1_NULL:
        result = 0;             /* They do not have content. */
        break;
    case V_ASN1_BOOLEAN:
        result = a->value.boolean - b->value.boolean;
        break;
    case V_ASN1_INTEGER:
    case V_ASN1_NEG_INTEGER:
    case V_ASN1_ENUMERATED:
    case V_ASN1_NEG_ENUMERATED:
    case V_ASN1_BIT_STRING:
    case V_ASN1_OCTET_STRING:
    case V_ASN1_SEQUENCE:
    case V_ASN1_SET:
    case V_ASN1_NUMERICSTRING:
    case V_ASN1_PRINTABLESTRING:
    case V_ASN1_T61STRING:
    case V_ASN1_VIDEOTEXSTRING:
    case V_ASN1_IA5STRING:
    case V_ASN1_UTCTIME:
    case V_ASN1_GENERALIZEDTIME:
    case V_ASN1_GRAPHICSTRING:
    case V_ASN1_VISIBLESTRING:
    case V_ASN1_GENERALSTRING:
    case V_ASN1_UNIVERSALSTRING:
    case V_ASN1_BMPSTRING:
    case V_ASN1_UTF8STRING:
    case V_ASN1_OTHER:
    default:
        result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
                                 (ASN1_STRING *)b->value.ptr);
        break;
    }

    return result;
}
Exemplo n.º 11
0
int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b)
	{
	int i,j;
	X509_NAME_ENTRY *na,*nb;

	if (sk_X509_NAME_ENTRY_num(a->entries)
	    != sk_X509_NAME_ENTRY_num(b->entries))
		return sk_X509_NAME_ENTRY_num(a->entries)
		  -sk_X509_NAME_ENTRY_num(b->entries);
	for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
		{
		na=sk_X509_NAME_ENTRY_value(a->entries,i);
		nb=sk_X509_NAME_ENTRY_value(b->entries,i);
		j=na->value->type-nb->value->type;
		if (j) return(j);
		if (na->value->type == V_ASN1_PRINTABLESTRING)
			j=nocase_spacenorm_cmp(na->value, nb->value);
		else if (na->value->type == V_ASN1_IA5STRING
			&& OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
			j=nocase_cmp(na->value, nb->value);
		else
			{
			j=na->value->length-nb->value->length;
			if (j) return(j);
			j=memcmp(na->value->data,nb->value->data,
				na->value->length);
			}
		if (j) return(j);
		j=na->set-nb->set;
		if (j) return(j);
		}

	/* We will check the object types after checking the values
	 * since the values will more often be different than the object
	 * types. */
	for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
		{
		na=sk_X509_NAME_ENTRY_value(a->entries,i);
		nb=sk_X509_NAME_ENTRY_value(b->entries,i);
		j=OBJ_cmp(na->object,nb->object);
		if (j) return(j);
		}
	return(0);
	}
Exemplo n.º 12
0
/* NOTE: you should be passsing -1, not 0 as lastpos */
int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
	     int lastpos)
	{
	int n;
	X509_NAME_ENTRY *ne;
	STACK_OF(X509_NAME_ENTRY) *sk;

	if (name == NULL) return(-1);
	if (lastpos < 0)
		lastpos= -1;
	sk=name->entries;
	n=sk_X509_NAME_ENTRY_num(sk);
	for (lastpos++; lastpos < n; lastpos++)
		{
		ne=sk_X509_NAME_ENTRY_value(sk,lastpos);
		if (OBJ_cmp(ne->object,obj) == 0)
			return(lastpos);
		}
	return(-1);
	}
Exemplo n.º 13
0
static int X509_NAME_wildcmp(const X509_NAME *a, const X509_NAME *b)
{
    int i,j;
    X509_NAME_ENTRY *na,*nb;

    if (sk_X509_NAME_ENTRY_num(a->entries)
	!= sk_X509_NAME_ENTRY_num(b->entries))
	    return sk_X509_NAME_ENTRY_num(a->entries)
	      -sk_X509_NAME_ENTRY_num(b->entries);
    for (i=sk_X509_NAME_ENTRY_num(a->entries)-1; i>=0; i--)
    {
	    na=sk_X509_NAME_ENTRY_value(a->entries,i);
	    nb=sk_X509_NAME_ENTRY_value(b->entries,i);
	    j=OBJ_cmp(na->object,nb->object);
	    if (j) return(j);
	    if ((na->value->length == 1 && na->value->data[0] == '*')
	     || (nb->value->length == 1 && nb->value->data[0] == '*'))
		    continue;
	    j=na->value->type-nb->value->type;
	    if (j) return(j);
	    if (na->value->type == V_ASN1_PRINTABLESTRING)
		    j=nocase_spacenorm_cmp(na->value, nb->value);
	    else if (na->value->type == V_ASN1_IA5STRING
		    && OBJ_obj2nid(na->object) == NID_pkcs9_emailAddress)
		    j=nocase_cmp(na->value, nb->value);
	    else
		    {
		    j=na->value->length-nb->value->length;
		    if (j) return(j);
		    j=memcmp(na->value->data,nb->value->data,
			    na->value->length);
		    }
	    if (j) return(j);
	    j=na->set-nb->set;
	    if (j) return(j);
    }

    return(0);
}
Exemplo n.º 14
0
/* Returns 0 if they are equal, != 0 otherwise. */
int
GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
{
	int result = -1;

	if (!a || !b || a->type != b->type)
		return -1;
	switch (a->type) {
	case GEN_X400:
	case GEN_EDIPARTY:
		result = ASN1_TYPE_cmp(a->d.other, b->d.other);
		break;

	case GEN_OTHERNAME:
		result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
		break;

	case GEN_EMAIL:
	case GEN_DNS:
	case GEN_URI:
		result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
		break;

	case GEN_DIRNAME:
		result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
		break;

	case GEN_IPADD:
		result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
		break;

	case GEN_RID:
		result = OBJ_cmp(a->d.rid, b->d.rid);
		break;
	}
	return result;
}
Exemplo n.º 15
0
static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
	{
	STACK_OF(CMS_SignerInfo) *sinfos;
	CMS_SignerInfo *sitmp;
	int i;
	sinfos = CMS_get0_SignerInfos(cms);
	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)
		{
		ASN1_OCTET_STRING *messageDigest;
		sitmp = sk_CMS_SignerInfo_value(sinfos, i);
		if (sitmp == si)
			continue;
		if (CMS_signed_get_attr_count(sitmp) < 0)
			continue;
		if (OBJ_cmp(si->digestAlgorithm->algorithm,
				sitmp->digestAlgorithm->algorithm))
			continue;
		messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
					OBJ_nid2obj(NID_pkcs9_messageDigest),
					-3, V_ASN1_OCTET_STRING);
		if (!messageDigest)
			{
			CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
			return 0;
			}

		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
						V_ASN1_OCTET_STRING,
						messageDigest, -1))
			return 1;
		else
			return 0;
		}
		CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
		return 0;
	}
Exemplo n.º 16
0
static int node_cmp(const X509_POLICY_NODE *const *a,
                    const X509_POLICY_NODE *const *b)
{
    return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy);
}
Exemplo n.º 17
0
LiteralValue_Priv::LiteralValue_Priv(GENERAL_NAME *gen)
	: LiteralValue()
{
	char oline[256], htmp[5];
	unsigned char *p = NULL;
	int nid = 0;
	int i;

	ASN1_OBJECT *id_ms_san_upn;
	ASN1_OBJECT *id_pkinit_san;

#define CREATE_OBJ_IF_NEEDED(oid, vn, sn, ln)					\
	nid = OBJ_txt2nid(oid);										\
		if (nid == NID_undef) {									\
		nid = OBJ_create(oid, sn, ln);							\
		if (nid == NID_undef) {									\
		LOGIT_ERROR("Error creating oid object for " << oid);	\
		return;													\
}															    \
}																\
		vn = OBJ_nid2obj(nid);

	CREATE_OBJ_IF_NEEDED("1.3.6.1.5.2.2", id_pkinit_san,
	                     "id-pkinit-san", "KRB5PrincipalName");

	CREATE_OBJ_IF_NEEDED("1.3.6.1.4.1.311.20.2.3", id_ms_san_upn,
	                     "id-ms-san-upn", "Microsoft Universal Principal Name");

	switch (gen->type)
	{
	case GEN_EMAIL:
		setLiteral("email", asn1string2string(gen->d.ia5));
		break;

	case GEN_DNS:
		setLiteral("DNS", asn1string2string(gen->d.ia5));
		break;

	case GEN_URI:
		setLiteral("URI", asn1string2string(gen->d.ia5));
		break;

	case GEN_DIRNAME:
		X509_NAME_oneline(gen->d.dirn, oline, 256);
		setLiteral("DirName", oline);
		break;

	case GEN_IPADD:
		p = gen->d.ip->data;
			/* BUG: doesn't support IPV6 */
		if(gen->d.ip->length == 4) {
			BIO_snprintf(oline, sizeof oline,
						 "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
		}
		else if(gen->d.ip->length == 16)
		{
			oline[0] = 0;
			for (i = 0; i < 8; i++)
			{
				BIO_snprintf(htmp, sizeof htmp,
							 "%X", p[0] << 8 | p[1]);
				p += 2;
				strcat(oline, htmp);
				if (i != 7)
					strcat(oline, ":");
			}
		}
		else
		{
			LOGIT_ERROR("Invalid IP Address");
			CA_MGM_THROW(ca_mgm::SyntaxException, "Invalid IP Address");
			break;
		}
		setLiteral("IP", oline);
		break;
	case GEN_RID:
		i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
		setLiteral("RID", oline);
		break;
	case GEN_OTHERNAME:
			// krb5PrincipalName || Microsoft Universal Principal Name
		if(OBJ_cmp(id_pkinit_san, gen->d.otherName->type_id) == 0)
		{
			decode_krb5_principal_name(gen->d.otherName->value->value.sequence->data,
			                           gen->d.otherName->value->value.sequence->length);
		}
		else if (OBJ_cmp(id_ms_san_upn, gen->d.otherName->type_id) == 0)
		{
			setLiteral("1.3.6.1.4.1.311.20.2.3", (char*)gen->d.otherName->value->value.sequence->data);
		}
		else
		{
			setLiteral("othername",
			           std::string("unsupported(") + str::numstring(OBJ_obj2nid(gen->d.otherName->type_id)) + ")");
		}
		break;
	case GEN_X400:
		setLiteral("X400Name", "unsupported");
		break;
	case GEN_EDIPARTY:
		setLiteral("EdiPartyName", "unsupported");
		break;
	}
}
Exemplo n.º 18
0
ASN1_OCTET_STRING	*sigattr_asn1_octet(scep_t *scep, char *attrname) {
	STACK_OF(X509_ATTRIBUTE)	*sig_attribs;
	ASN1_OBJECT			*asn1_obj;
	ASN1_TYPE			*asn1_type;
	X509_ATTRIBUTE			*attr;
	int				i;
	scepmsg_t			*msg;
	int single;
	
	if (debug)
		BIO_printf(bio_err, "%s:%d: looking for attribute '%s'\n",
			__FILE__, __LINE__, attrname);

	/* decide which message to study: client reads attrs from reply	*/
	if (scep->client)
		msg = &scep->reply;
	else
		msg = &scep->request;

	/* find the object we by name					*/
	asn1_obj = OBJ_nid2obj(OBJ_sn2nid(attrname));
	asn1_type = NULL;

	/* retrieve the stack of signed attributes			*/
	if (NULL == (sig_attribs = PKCS7_get_signed_attributes(msg->si))) {
		BIO_printf(bio_err, "%s:%d: signed attributes not found\n",
			__FILE__, __LINE__);
		return NULL;
	}

	/* scan all attributes for the one we are looking for		*/
	for (i = 0; i < sk_X509_ATTRIBUTE_num(sig_attribs); i++) {
		attr = sk_X509_ATTRIBUTE_value(sig_attribs, i);
		if (OBJ_cmp(attr->object, asn1_obj) == 0) {
#if OPENSSL_VERSION_NUMBER < 0x00907000L
			/* attr->set was replaced with attr->single (with opposite
			   meaning) somewhere between 0.9.6m-engine and 0.9.7d */
			single = !attr->set;
#else
			single = attr->single;
#endif
			if (single || (sk_ASN1_TYPE_num(attr->value.set) == 0)) {
 				BIO_printf(bio_err, "%s:%d: attr has no val\n",__FILE__, __LINE__);
				goto err;
 				 					 				
				BIO_printf(bio_err, "%s:%d: attr has no val\n",
					__FILE__, __LINE__);
				goto err;
			}
			if (debug)
				BIO_printf(bio_err, "%s:%d: found matching "
					"attribute with %d values\n", __FILE__,
					__LINE__,
					sk_ASN1_TYPE_num(attr->value.set));
			asn1_type = sk_ASN1_TYPE_value(attr->value.set, 0);
			if (debug)
				BIO_printf(bio_err, "%s:%d: type found: %p\n",
					__FILE__, __LINE__, asn1_type);
			break;
		}
	}

	/* if we cannot find the required argument, we just return NULL	*/
	if (debug)
		BIO_printf(bio_err, "%s:%d: checking for attribute\n",
			__FILE__, __LINE__);
	if (asn1_type == NULL) {
		BIO_printf(bio_err, "%s:%d: attribute has no type\n",
			__FILE__, __LINE__);
		goto err;
	}
	if (ASN1_TYPE_get(asn1_type) != V_ASN1_OCTET_STRING) {
		BIO_printf(bio_err, "%s:%d: attribute has wrong type\n",
			__FILE__, __LINE__);
		goto err;
	}
	if (debug)
		BIO_printf(bio_err, "%s:%d: found attribute '%s'\n", 
			__FILE__, __LINE__, attrname);

	/* this is an ASN1_OCTET_STRING, so we can retrieve the 	*/
	/* appropriate element of the union				*/
	return asn1_type->value.octet_string;

	/* error return, or attribute not found				*/
err:
	if (debug)
		BIO_printf(bio_err, "%s:%d: attribute not found or error\n",
			__FILE__, __LINE__);
	ERR_print_errors(bio_err);
	return NULL;
}
Exemplo n.º 19
0
/*
 * read an attribute of type string
 */
char	*sigattr_string(scep_t *scep, char *attrname) {
	STACK_OF(X509_ATTRIBUTE)	*sig_attribs;
	ASN1_OBJECT			*asn1_obj;
	ASN1_TYPE			*asn1_type;
	X509_ATTRIBUTE			*attr;
	int				len, i;
	char				*data = NULL;
	scepmsg_t			*msg;
	
	if (debug)
		BIO_printf(bio_err, "%s:%d: looking for attribute '%s'\n",
			__FILE__, __LINE__, attrname);

	/* decide which message to study: client reads attrs from reply	*/
	if (scep->client)
		msg = &scep->reply;
	else
		msg = &scep->request;

	/* find the object we by name					*/
	asn1_obj = OBJ_nid2obj(OBJ_sn2nid(attrname));
	asn1_type = NULL;

	/* retrieve the stack of signed attributes			*/
	if (NULL == (sig_attribs = PKCS7_get_signed_attributes(msg->si))) {
		BIO_printf(bio_err, "%s:%d: no signed attributes\n",
			__FILE__, __LINE__);
		return NULL;
	}

	/* scan all attributes for the one we are looking for		*/
	for (i = 0; i < sk_X509_ATTRIBUTE_num(sig_attribs); i++) {
		attr = sk_X509_ATTRIBUTE_value(sig_attribs, i);
		if (OBJ_cmp(attr->object, asn1_obj) == 0) {
			if (debug)
				BIO_printf(bio_err, "%s:%d: found attribute\n",
					__FILE__, __LINE__);
			asn1_type = sk_ASN1_TYPE_value(attr->value.set, 0);
			break;
		}
	}

	/* if we cannot find the required argument, we just return NULL	*/
	if (asn1_type == NULL) {
		BIO_printf(bio_err, "%s:%d: cannot find attribute\n",
			__FILE__, __LINE__);
		goto err;
	}
	if (ASN1_TYPE_get(asn1_type) != V_ASN1_PRINTABLESTRING) {
		BIO_printf(bio_err, "%s:%d: attribute has wrong type\n",
			__FILE__, __LINE__);
		goto err;
	}

	if (debug)
		BIO_printf(bio_err, "%s:%d: found attribute '%s'\n", 
			__FILE__, __LINE__, attrname);
	/* unpack the ASN1_STRING into a C-String (0-terminated)	*/
	len = ASN1_STRING_length(asn1_type->value.asn1_string);
	data = (char *)malloc(1 + len);
	memcpy(data, ASN1_STRING_data(asn1_type->value.asn1_string), len);
	data[len] = '\0';
	if (debug)
		BIO_printf(bio_err, "%s:%d: value of %d bytes retrieved\n",
			__FILE__, __LINE__, len);

	/* return the data						*/
	return data;
err:
	ERR_print_errors(bio_err);
	return NULL;
}
Exemplo n.º 20
0
int ndn_verify_signature(const unsigned char *msg,
                     size_t size,
                     const struct ndn_parsed_ContentObject *co,
                     const struct ndn_pkey *verification_pubkey)
{
    EVP_MD_CTX verc;
    EVP_MD_CTX *ver_ctx = &verc;
    X509_SIG *digest_info = NULL;
    const unsigned char *dd = NULL;
    MP_info *merkle_path_info = NULL;
    unsigned char *root_hash = NULL;
    size_t root_hash_size;

    int res;

    const EVP_MD *digest = NULL;
    const EVP_MD *merkle_path_digest = NULL;
    
    const unsigned char *signature_bits = NULL;
    size_t signature_bits_size = 0;
    const unsigned char *witness = NULL;
    size_t witness_size = 0;
    const unsigned char *digest_algorithm = NULL;
    size_t digest_algorithm_size;
    
    EVP_PKEY *pkey = (EVP_PKEY *)verification_pubkey;

    res = ndn_ref_tagged_BLOB(NDN_DTAG_SignatureBits, msg,
                              co->offset[NDN_PCO_B_SignatureBits],
                              co->offset[NDN_PCO_E_SignatureBits],
                              &signature_bits,
                              &signature_bits_size);
    if (res < 0)
        return (-1);

    if (co->offset[NDN_PCO_B_DigestAlgorithm] == co->offset[NDN_PCO_E_DigestAlgorithm]) {
        digest_algorithm = (const unsigned char *)NDN_SIGNING_DEFAULT_DIGEST_ALGORITHM;
    }
    else {
        /* figure out what algorithm the OID represents */
        res = ndn_ref_tagged_string(NDN_DTAG_DigestAlgorithm, msg,
                                  co->offset[NDN_PCO_B_DigestAlgorithm],
                                  co->offset[NDN_PCO_E_DigestAlgorithm],
                                  &digest_algorithm,
                                  &digest_algorithm_size);
        if (res < 0)
            return (-1);
        /* NOTE: since the element closer is a 0, and the element is well formed,
         * the string will be null terminated 
         */
    }
    digest = md_from_digest_and_pkey((const char *)digest_algorithm, verification_pubkey);
    EVP_MD_CTX_init(ver_ctx);
    res = EVP_VerifyInit_ex(ver_ctx, digest, NULL);
    if (!res) {
        EVP_MD_CTX_cleanup(ver_ctx);
        return (-1);
    }
    if (co->offset[NDN_PCO_B_Witness] != co->offset[NDN_PCO_E_Witness]) {
        /* The witness is a DigestInfo, where the octet-string therein encapsulates
         * a sequence of [integer (origin 1 node#), sequence of [octet-string]]
         * where the inner octet-string is the concatenated hashes on the merkle-path
         */
        res = ndn_ref_tagged_BLOB(NDN_DTAG_Witness, msg,
                                  co->offset[NDN_PCO_B_Witness],
                                  co->offset[NDN_PCO_E_Witness],
                                  &witness,
                                  &witness_size);
        if (res < 0) {
            EVP_MD_CTX_cleanup(ver_ctx);
            return (-1);
        }

        digest_info = d2i_X509_SIG(NULL, &witness, witness_size);
        /* digest_info->algor->algorithm->{length, data}
         * digest_info->digest->{length, type, data}
         */
        /* ...2.2 is an MHT w/ SHA256 */
        ASN1_OBJECT *merkle_hash_tree_oid = OBJ_txt2obj("1.2.840.113550.11.1.2.2", 1);
        if (0 != OBJ_cmp(digest_info->algor->algorithm, merkle_hash_tree_oid)) {
            fprintf(stderr, "A witness is present without an MHT OID!\n");
            EVP_MD_CTX_cleanup(ver_ctx);
            ASN1_OBJECT_free(merkle_hash_tree_oid);
            return (-1);
        }
        /* we're doing an MHT */
        ASN1_OBJECT_free(merkle_hash_tree_oid);
        merkle_path_digest = EVP_sha256();
        /* DER-encoded in the digest_info's digest ASN.1 octet string is the Merkle path info */
        dd = digest_info->digest->data;
        merkle_path_info = d2i_MP_info(NULL, &dd, digest_info->digest->length);
        X509_SIG_free(digest_info);
#ifdef DEBUG
        int x,h;
        int node = ASN1_INTEGER_get(merkle_path_info->node);
        int hash_count = sk_ASN1_OCTET_STRING_num(merkle_path_info->hashes);
        ASN1_OCTET_STRING *hash;
        fprintf(stderr, "A witness is present with an MHT OID\n");
        fprintf(stderr, "This is node %d, with %d hashes\n", node, hash_count);
        for (h = 0; h < hash_count; h++) {
            hash = sk_ASN1_OCTET_STRING_value(merkle_path_info->hashes, h);
            fprintf(stderr, "     hashes[%d] len = %d data = ", h, hash->length);
            for (x = 0; x < hash->length; x++) {
                fprintf(stderr, "%02x", hash->data[x]);
            }
            fprintf(stderr, "\n");
        }
#endif
        /* In the MHT signature case, we signed/verify the root hash */
        root_hash_size = EVP_MD_size(merkle_path_digest);
        root_hash = calloc(1, root_hash_size);
        res = ndn_merkle_root_hash(msg, size, co, merkle_path_digest, merkle_path_info, root_hash, root_hash_size);
        MP_info_free(merkle_path_info);
        if (res < 0) {
            EVP_MD_CTX_cleanup(ver_ctx);
            free(root_hash);
            return(-1);
        }
        res = EVP_VerifyUpdate(ver_ctx, root_hash, root_hash_size);
        free(root_hash);
        if (res == 0) {
            EVP_MD_CTX_cleanup(ver_ctx);
            return(-1);
        }
        res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey);
        EVP_MD_CTX_cleanup(ver_ctx);
    } else {
        /*
         * In the simple signature case, we signed/verify from the name through
         * the end of the content.
         */
        size_t signed_size = co->offset[NDN_PCO_E_Content] - co->offset[NDN_PCO_B_Name];
        res = EVP_VerifyUpdate(ver_ctx, msg + co->offset[NDN_PCO_B_Name], signed_size);
        if (res == 0) {
            EVP_MD_CTX_cleanup(ver_ctx);
            return(-1);
        }
        res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey);
        EVP_MD_CTX_cleanup(ver_ctx);
    }
    return (res);
}
Exemplo n.º 21
0
		inline int compare(const object& lhs, const object& rhs)
		{
			return OBJ_cmp(lhs.raw(), rhs.raw());
		}
Exemplo n.º 22
0
static int ref_cmp(const X509_POLICY_REF * const *a,
			const X509_POLICY_REF * const *b)
	{
	return OBJ_cmp((*a)->subjectDomainPolicy, (*b)->subjectDomainPolicy);
	}
Exemplo n.º 23
0
int ccn_verify_signature(const unsigned char *msg,
                     size_t size,
                     const struct ccn_parsed_ContentObject *co,
                     const struct ccn_pkey *verification_pubkey)
{
    EVP_MD_CTX verc;
    EVP_MD_CTX *ver_ctx = &verc;
    X509_SIG *digest_info = NULL;
    MP_info *merkle_path_info = NULL;
    unsigned char *root_hash;
    size_t root_hash_size;

    int res;

    const EVP_MD *digest = EVP_md_null();
    const EVP_MD *merkle_path_digest = EVP_md_null();

    const unsigned char *signature_bits = NULL;
    size_t signature_bits_size = 0;
    const unsigned char *witness = NULL;
    size_t witness_size = 0;
    EVP_PKEY *pkey = (EVP_PKEY *)verification_pubkey;
#ifdef DEBUG
    int x, h;
#endif

    res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, msg,
                              co->offset[CCN_PCO_B_SignatureBits],
                              co->offset[CCN_PCO_E_SignatureBits],
                              &signature_bits,
                              &signature_bits_size);
    if (res < 0)
        return (-1);

    if (co->offset[CCN_PCO_B_DigestAlgorithm] == co->offset[CCN_PCO_E_DigestAlgorithm]) {
        digest = EVP_sha256();
    }
    else {
        /* XXX - figure out what algorithm the OID represents */
        fprintf(stderr, "not a DigestAlgorithm I understand right now\n");
        return (-1);
    }

    EVP_MD_CTX_init(ver_ctx);
    res = EVP_VerifyInit_ex(ver_ctx, digest, NULL);
    if (!res)
        return (-1);

    if (co->offset[CCN_PCO_B_Witness] != co->offset[CCN_PCO_E_Witness]) {
        /* The witness is a DigestInfo, where the octet-string therein encapsulates
         * a sequence of [integer (origin 1 node#), sequence of [octet-string]]
         * where the inner octet-string is the concatenated hashes on the merkle-path
         */
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Witness, msg,
                                  co->offset[CCN_PCO_B_Witness],
                                  co->offset[CCN_PCO_E_Witness],
                                  &witness,
                                  &witness_size);
        if (res < 0)
            return (-1);


        digest_info = d2i_X509_SIG(NULL, &witness, witness_size);
        /* digest_info->algor->algorithm->{length, data}
         * digest_info->digest->{length, type, data}
         */
        /* ...2.2 is an MHT w/ SHA256 */
        ASN1_OBJECT *merkle_hash_tree_oid = OBJ_txt2obj("1.2.840.113550.11.1.2.2", 1);
        if (0 != OBJ_cmp(digest_info->algor->algorithm, merkle_hash_tree_oid)) {
            fprintf(stderr, "A witness is present without an MHT OID!\n");
            ASN1_OBJECT_free(merkle_hash_tree_oid);
            return (-1);
        }
        /* we're doing an MHT */
        ASN1_OBJECT_free(merkle_hash_tree_oid);
        merkle_path_digest = EVP_sha256();
        /* DER-encoded in the digest_info's digest ASN.1 octet string is the Merkle path info */
        merkle_path_info = d2i_MP_info(NULL, (const unsigned char **)&(digest_info->digest->data), digest_info->digest->length);
#ifdef DEBUG
        int node = ASN1_INTEGER_get(merkle_path_info->node);
        int hash_count = merkle_path_info->hashes->num;
        ASN1_OCTET_STRING *hash;
        fprintf(stderr, "A witness is present with an MHT OID\n");
        fprintf(stderr, "This is node %d, with %d hashes\n", node, hash_count);
        for (h = 0; h < hash_count; h++) {
            hash = (ASN1_OCTET_STRING *)merkle_path_info->hashes->data[h];
            fprintf(stderr, "     hashes[%d] len = %d data = ", h, hash->length);
            for (x = 0; x < hash->length; x++) {
                fprintf(stderr, "%02x", hash->data[x]);
            }
            fprintf(stderr, "\n");
        }
#endif
        /* In the MHT signature case, we signed/verify the root hash */
        root_hash_size = EVP_MD_size(merkle_path_digest);
        root_hash = calloc(1, root_hash_size);
        res = ccn_merkle_root_hash(msg, size, co, merkle_path_digest, merkle_path_info, root_hash, root_hash_size);
        res = EVP_VerifyUpdate(ver_ctx, root_hash, root_hash_size);
        res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey);
        EVP_MD_CTX_cleanup(ver_ctx);
    } else {
        /*
         * In the simple signature case, we signed/verify from the name through
         * the end of the content.
         */
        size_t signed_size = co->offset[CCN_PCO_E_Content] - co->offset[CCN_PCO_B_Name];
        res = EVP_VerifyUpdate(ver_ctx, msg + co->offset[CCN_PCO_B_Name], signed_size);
        res = EVP_VerifyFinal(ver_ctx, signature_bits, signature_bits_size, pkey);
        EVP_MD_CTX_cleanup(ver_ctx);
    }

    if (res == 1)
        return (1);
    else
        return (0);
}
Exemplo n.º 24
0
int main(int argc, char **argv)
{
	int debug=0;
	int verify=0;
	int mismatch=0;
	char *program;
	int badops=0;
	char *certfile=NULL;
	char *out1file=NULL;
	char *out2file=NULL;
	char *home=NULL;
	char *pin=NULL;
	char *argp;
	char *ss;
	BIO *bio_err;
	X509 *ucert;

	FILE *fp;
	FILE *fpout;

#ifdef USE_PKCS11
    CK_SESSION_HANDLE hSession = 0;
#endif


#ifdef WIN32
	CRYPTO_malloc_init();
#endif

	ERR_load_prxyerr_strings(0);
	SSLeay_add_ssl_algorithms();

	if ((bio_err=BIO_new(BIO_s_file())) != NULL) {
        BIO_set_fp(bio_err,stderr,BIO_NOCLOSE);
	}

	program=argv[0];
	argc--;
	argv++;
	while (argc >= 1) {
		argp = *argv;
		if ( *argp == '-' && *(argp+1) == '-') {
			argp++;
		}
		if  (strcmp(argp,"-debug") == 0) {
			debug++;
		}
		else if (strcmp(argp,"-cert") == 0) {
			if (--argc < 1) goto bad;
			certfile=*(++argv);
		} 
		else if (strcmp(argp,"-out1") == 0) {
			if (--argc < 1) goto bad;
			out1file=*(++argv);
		} 
		else if (strcmp(argp,"-out2") == 0) {
			if (--argc < 1) goto bad;
			out2file=*(++argv);
		} 
		else if (strcmp(argp,"-help") == 0) {
			badops=1;
			break;
		}
		else {
			fprintf(stderr,_GGSL("unknown option %s\n"),*argv);
			badops=1;
			break;
		}
		argc--;
		argv++;
	}

	if (badops) {
bad:
		fprintf(stderr,_GGSL("%s [options]\n"),program);
		fprintf(stderr,_GGSL("where options  are\n"));
		fprintf(stderr,_GGSL(" --help    show this list\n"));
		fprintf(stderr,_GGSL(" --debug   set debugging on\n"));
		fprintf(stderr,_GGSL(" --cert    file name of long term certificate\n"));
		fprintf(stderr,_GGSL(" --out1     file name for name\n"));
		fprintf(stderr,_GGSL(" --out2    file name for commonName\n");
		exit(1);
	}
	home = (char *)getenv("HOME");
	if (home == NULL) {
#ifndef WIN32
		fprintf(stderr,_GGSL("$HOME not defined"));
		exit(1);
#else
		home = "c:\\windows";
#endif
	}

	if (!strncmp(certfile,"SC:",3)) {
#ifdef USE_PKCS11
        char *cp;
        char *kp;
        int rc;
        cp = certfile + 3;
        kp = strchr(cp,':');
        if (kp == NULL) {
            fprintf(stderr,_GGSL("Bad format of cert name, SC:card:cert\n"));
            exit (2);
        }
        kp++; /* skip the : */
        if (hSession == 0) {
            rc = sc_init(&hSession, cp, NULL, pin, CKU_USER, 0);
            if (rc) {
                fprintf(stderr,_GGSL("Failed to open card session\n"));
                ERR_print_errors_fp (stderr);
                exit(2);
            }
        }


        rc = sc_get_cert_obj_by_label(hSession,kp,&ucert);
        if (rc) {
            fprintf(stderr,_GGSL("Failed to find certificate on card \n"));
            ERR_print_errors_fp (stderr);
            exit(2);
        }
#else
        fprintf(stderr,_GGSL("Smart card support not compiled with this program\n"));
            exit (2);
#endif /* USE_PKCS11 */

	} else {
		fp = fopen (certfile, "r");
		if (fp == NULL) {
			fprintf(stderr,_GGSL(" failed to open %s\n",certfile));
	 		exit (1);
		}

		ucert = PEM_read_X509 (fp, NULL, OPENSSL_PEM_CB(NULL, NULL));
		fclose (fp);
}

	if (ucert == NULL) {
		ERR_print_errors_fp (stderr);
		exit (1); 
	}

	if (out1file) {
		if (strcmp("-",out1file)) {
			fpout=fopen(out1file,"w");
		} else {
			fpout = stdout;
		}
		if (fpout == NULL) {
			fprintf (stderr,"Unable to open out1 file:%s\n", out1file);
			exit(4);
		}
		ss = X509_NAME_oneline(ucert->cert_info->subject,NULL,0);
		while (1) {
			if (!strcmp(ss+strlen(ss)-strlen("/CN=limited proxy"),
								"/CN=limited proxy")) {
				*(ss+strlen(ss)-strlen("/CN=limited proxy"))= '\0';
			} else
			if (!strcmp(ss+strlen(ss)-strlen("/CN=proxy"),
					"/CN=proxy")) {
				*(ss+strlen(ss)-strlen("/CN=proxy")) = '\0';
			} else {
				break;
			}
		}
		
		fprintf(fpout,"%s\n",ss);
		OPENSSL_free(ss);

		if (fpout != stdout) {
			fclose(fpout);
		}
	}


	if (out2file) {
		if (strcmp("-",out2file)) {
			fpout=fopen(out2file,"w");
		} else {
			fpout = stdout;
		}
		if (fpout == NULL) {
			fprintf (stderr,"Unable to open out2 file:%s\n", out2file);
			exit(4);
		}
		{
			X509_NAME *subject;
			X509_NAME_ENTRY *ne;
			ASN1_STRING *data;
			X509_NAME_ENTRY *o = NULL;
			X509_NAME_ENTRY *ou1 = NULL;
			X509_NAME_ENTRY *ou2 = NULL;
			int i;
	
			subject=X509_get_subject_name(ucert);
			i = X509_NAME_entry_count(subject)-1;
			while (i > 0) {
				ne=X509_NAME_get_entry(subject,i);
				if (!OBJ_cmp(ne->object,
						OBJ_nid2obj(NID_organizationName))) {
					if (!o) {
						o = ne;
					}
				}
				if (!OBJ_cmp(ne->object,
						OBJ_nid2obj(NID_organizationalUnitName))) {
					if (ou2) { 
						ou1 = ne;
					} else { 
						ou2 = ne;
					}
				}
				if (!OBJ_cmp(ne->object,
						OBJ_nid2obj(NID_commonName))) {
					data=X509_NAME_ENTRY_get_data(ne);
					if ((data->length == 5 &&
							!memcmp(data->data,"proxy",5)) ||
						(data->length == 13 &&
							!memcmp(data->data,"limited proxy",13))) {
							i--;
							continue;
					}
					fprintf(fpout,"%.*s\n",data->length,data->data);
					/* break; */
				}	
				i--;
			} 
			if (o) {
				data=X509_NAME_ENTRY_get_data(o);
				fprintf(fpout,"%.*s\n",data->length,data->data);
			}
			if (ou1) {
				data=X509_NAME_ENTRY_get_data(ou1);
				fprintf(fpout,"%.*s\n",data->length,data->data);
			}
			if (ou2) {
				data=X509_NAME_ENTRY_get_data(ou2);
				fprintf(fpout,"%.*s\n",data->length,data->data);
			}
		} /* inline section */
			

		if (fpout != stdout) {
			fclose(fpout);
		}
	} /* out2file */

	return 0;

}
Exemplo n.º 25
0
static int
tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in )
{
	tlso_session *s = (tlso_session *)sess;
	int i, ret = LDAP_LOCAL_ERROR;
	X509 *x;
	const char *name;
	char *ptr;
	int ntype = IS_DNS, nlen;
#ifdef LDAP_PF_INET6
	struct in6_addr addr;
#else
	struct in_addr addr;
#endif

	if( ldap_int_hostname &&
		( !name_in || !strcasecmp( name_in, "localhost" ) ) )
	{
		name = ldap_int_hostname;
	} else {
		name = name_in;
	}
	nlen = strlen(name);

	x = tlso_get_cert(s);
	if (!x) {
		Debug( LDAP_DEBUG_ANY,
			"TLS: unable to get peer certificate.\n",
			0, 0, 0 );
		/* If this was a fatal condition, things would have
		 * aborted long before now.
		 */
		return LDAP_SUCCESS;
	}

#ifdef LDAP_PF_INET6
	if (inet_pton(AF_INET6, name, &addr)) {
		ntype = IS_IP6;
	} else 
#endif
	if ((ptr = strrchr(name, '.')) && isdigit((unsigned char)ptr[1])) {
		if (inet_aton(name, (struct in_addr *)&addr)) ntype = IS_IP4;
	}
	
	i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1);
	if (i >= 0) {
		X509_EXTENSION *ex;
		STACK_OF(GENERAL_NAME) *alt;

		ex = X509_get_ext(x, i);
		alt = X509V3_EXT_d2i(ex);
		if (alt) {
			int n, len2 = 0;
			char *domain = NULL;
			GENERAL_NAME *gn;

			if (ntype == IS_DNS) {
				domain = strchr(name, '.');
				if (domain) {
					len2 = nlen - (domain-name);
				}
			}
			n = sk_GENERAL_NAME_num(alt);
			for (i=0; i<n; i++) {
				char *sn;
				int sl;
				gn = sk_GENERAL_NAME_value(alt, i);
				if (gn->type == GEN_DNS) {
					if (ntype != IS_DNS) continue;

					sn = (char *) ASN1_STRING_data(gn->d.ia5);
					sl = ASN1_STRING_length(gn->d.ia5);

					/* ignore empty */
					if (sl == 0) continue;

					/* Is this an exact match? */
					if ((nlen == sl) && !strncasecmp(name, sn, nlen)) {
						break;
					}

					/* Is this a wildcard match? */
					if (domain && (sn[0] == '*') && (sn[1] == '.') &&
						(len2 == sl-1) && !strncasecmp(domain, &sn[1], len2))
					{
						break;
					}

				} else if (gn->type == GEN_IPADD) {
					if (ntype == IS_DNS) continue;

					sn = (char *) ASN1_STRING_data(gn->d.ia5);
					sl = ASN1_STRING_length(gn->d.ia5);

#ifdef LDAP_PF_INET6
					if (ntype == IS_IP6 && sl != sizeof(struct in6_addr)) {
						continue;
					} else
#endif
					if (ntype == IS_IP4 && sl != sizeof(struct in_addr)) {
						continue;
					}
					if (!memcmp(sn, &addr, sl)) {
						break;
					}
				}
			}

			GENERAL_NAMES_free(alt);
			if (i < n) {	/* Found a match */
				ret = LDAP_SUCCESS;
			}
		}
	}

	if (ret != LDAP_SUCCESS) {
		X509_NAME *xn;
		X509_NAME_ENTRY *ne;
		ASN1_OBJECT *obj;
		ASN1_STRING *cn = NULL;
		int navas;

		/* find the last CN */
		obj = OBJ_nid2obj( NID_commonName );
		if ( !obj ) goto no_cn;	/* should never happen */

		xn = X509_get_subject_name(x);
		navas = X509_NAME_entry_count( xn );
		for ( i=navas-1; i>=0; i-- ) {
			ne = X509_NAME_get_entry( xn, i );
			if ( !OBJ_cmp( X509_NAME_ENTRY_get_object(ne), obj )) {
				cn = X509_NAME_ENTRY_get_data( ne );
				break;
			}
		}

		if( !cn )
		{
no_cn:
			Debug( LDAP_DEBUG_ANY,
				"TLS: unable to get common name from peer certificate.\n",
				0, 0, 0 );
			ret = LDAP_CONNECT_ERROR;
			if ( ld->ld_error ) {
				LDAP_FREE( ld->ld_error );
			}
			ld->ld_error = LDAP_STRDUP(
				_("TLS: unable to get CN from peer certificate"));

		} else if ( cn->length == nlen &&
			strncasecmp( name, (char *) cn->data, nlen ) == 0 ) {
			ret = LDAP_SUCCESS;

		} else if (( cn->data[0] == '*' ) && ( cn->data[1] == '.' )) {
			char *domain = strchr(name, '.');
			if( domain ) {
				int dlen;

				dlen = nlen - (domain-name);

				/* Is this a wildcard match? */
				if ((dlen == cn->length-1) &&
					!strncasecmp(domain, (char *) &cn->data[1], dlen)) {
					ret = LDAP_SUCCESS;
				}
			}
		}

		if( ret == LDAP_LOCAL_ERROR ) {
			Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
				"common name in certificate (%.*s).\n", 
				name, cn->length, cn->data );
			ret = LDAP_CONNECT_ERROR;
			if ( ld->ld_error ) {
				LDAP_FREE( ld->ld_error );
			}
			ld->ld_error = LDAP_STRDUP(
				_("TLS: hostname does not match CN in peer certificate"));
		}
	}
	X509_free(x);
	return ret;
}
Exemplo n.º 26
0
static int obj_cmp(const ASN1_OBJECT * const *a, const ASN1_OBJECT * const *b)
{
	return OBJ_cmp(*a, *b);
}
Exemplo n.º 27
0
static void CheckEKU(X509 *x509, CertType type)
{
	int idx = -1;
	bool first = true;

	do
	{
		int critical = -1;

		EXTENDED_KEY_USAGE *ekus = X509_get_ext_d2i(x509, NID_ext_key_usage, &critical, &idx);

		if (ekus == NULL)
		{
			if (critical >= 0)
			{
				/* Found but fails to parse */
				SetError(ERR_INVALID);
				continue;
			}
			/* Not found */
			if (first)
			{
				SetCertInfo(CERT_INFO_NO_EKU);
				if (type == SubscriberCertificate)
				{
					SetWarning(WARN_NO_EKU);
				}
			}
			break;
		}
		first = false;

		if (type == RootCA)
		{
			/* CAB 7.1.2.1d */
			SetError(ERR_ROOT_CA_WITH_EKU);
		}

		for (int i = 0; i < sk_ASN1_OBJECT_num(ekus); i++)
		{
			ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(ekus, i);
			int nid = OBJ_obj2nid(oid);
			if (OBJ_cmp(oid, obj_anyEKU) == 0)
			{
				SetCertInfo(CERT_INFO_ANY_EKU);
			}
			else if (nid == NID_server_auth)
			{
				SetCertInfo(CERT_INFO_SERV_AUTH);
			}
			else if (nid == NID_client_auth)
			{
				SetCertInfo(CERT_INFO_CLIENT_AUTH);
			}
			else if (nid == NID_code_sign)
			{
				SetCertInfo(CERT_INFO_CODE_SIGN);
			}
			else if (nid == NID_email_protect)
			{
				SetCertInfo(CERT_INFO_EMAIL);
			}
			else if (nid == NID_time_stamp)
			{
				SetCertInfo(CERT_INFO_TIME_STAMP);
			}
			else if (nid == NID_OCSP_sign)
			{
				SetCertInfo(CERT_INFO_OCSP_SIGN);
			}
			else if (OBJ_cmp(oid, obj_IntelAMTvProEKU) == 0)
			{
				SetCertInfo(CERT_INFO_AMTVPRO_EKU);
			}
			else
			{
				SetWarning(WARN_UNKNOWN_EKU);
			}
		}
		if (GetBit(cert_info, CERT_INFO_AMTVPRO_EKU) && !GetBit(cert_info, CERT_INFO_SERV_AUTH))
		{
			SetError(ERR_MISSING_EKU);
		}
		if (sk_ASN1_OBJECT_num(ekus) == 0)
		{
			SetError(ERR_EMPTY_EKU);
		}
		sk_ASN1_OBJECT_pop_free(ekus, ASN1_OBJECT_free);
	}
	while (1);
}
Exemplo n.º 28
0
static int policy_data_cmp(const X509_POLICY_DATA **a,
                           const X509_POLICY_DATA **b)
{
    return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy);
}
Exemplo n.º 29
0
static void CheckNameEntryValid(X509_NAME_ENTRY *ne)
{
	ASN1_STRING *data = X509_NAME_ENTRY_get_data(ne);
	ASN1_OBJECT *obj = X509_NAME_ENTRY_get_object(ne);
	int nid = OBJ_obj2nid(obj);
	size_t char_len;

	if (CheckStringValid(data, &char_len))
	{
		bool bChecked = false;
		for (size_t i = 0; i < sizeof(size_limits)/sizeof(size_limits[0]); i++)
		{
			if (OBJ_cmp(*size_limits[i].obj, obj) == 0)
			{
				if (char_len > size_limits[i].max || char_len < size_limits[i].min)
				{
					SetError(size_limits[i].error);
				}
				bChecked = true;
				break;
			}
		}
		if (!bChecked)
		{
			SetInfo(INF_NAME_ENTRY_LENGTH_NOT_CHECKED);
		}
	}

	if (nid == NID_pkcs9_emailAddress || nid == NID_domainComponent)
	{
		if (data->type != V_ASN1_IA5STRING)
		{
			SetError(ERR_INVALID_NAME_ENTRY_TYPE);
		}
	}
	else if (nid == NID_pkcs9_unstructuredName && data->type == V_ASN1_IA5STRING)
	{
		/* PKCS#9 unstructuredName may be IA5String or DirectoryString */
	}
	else
	{
		/* It should be a DirectoryString, which is one of the below */
		if ((data->type != V_ASN1_PRINTABLESTRING) &&
			(data->type != V_ASN1_UTF8STRING) &&
			(data->type != V_ASN1_T61STRING) &&
			(data->type != V_ASN1_UNIVERSALSTRING) &&
			(data->type != V_ASN1_BMPSTRING))
		{
			SetError(ERR_INVALID_NAME_ENTRY_TYPE);
		}
		else if ((data->type != V_ASN1_PRINTABLESTRING) && (data->type != V_ASN1_UTF8STRING))
		{
			/* RFC5280 says it MUST be PrintableString or UTF8String, with exceptions. */
			SetWarning(WARN_NON_PRINTABLE_STRING);
		}
	}

	if (nid == NID_countryName && data->type != V_ASN1_PRINTABLESTRING)
	{
		SetError(ERR_INVALID_NAME_ENTRY_TYPE);
	}
	if (nid == NID_dnQualifier && data->type != V_ASN1_PRINTABLESTRING)
	{
		SetError(ERR_INVALID_NAME_ENTRY_TYPE);
	}
	if (nid == NID_serialNumber && data->type != V_ASN1_PRINTABLESTRING)
	{
		SetError(ERR_INVALID_NAME_ENTRY_TYPE);
	}

	return;
}
Exemplo n.º 30
0
static void CheckSAN(X509 *x509, CertType type)
{
	int idx = -1;
	bool bSanFound = false;
	bool bSanName = false;
	bool bSanRequired = false;
	bool bCommonNameFound = false;
	ASN1_STRING *commonName = NULL;
	enum { SAN_TYPE_NOT_ALLOWED, SAN_TYPE_ALLOWED, SAN_TYPE_WARN } name_type_allowed[GEN_RID+1];

	for (int i = 0; i < GEN_RID+1; i++)
	{
		name_type_allowed[i] = SAN_TYPE_NOT_ALLOWED;
	}

	if (GetBit(cert_info, CERT_INFO_SERV_AUTH) || GetBit(cert_info, CERT_INFO_ANY_EKU) || GetBit(cert_info, CERT_INFO_NO_EKU))
	{
		name_type_allowed[GEN_DNS] = SAN_TYPE_ALLOWED;
		name_type_allowed[GEN_IPADD] = SAN_TYPE_ALLOWED;
		bSanRequired = true;
	}
	if (GetBit(cert_info, CERT_INFO_EMAIL) || GetBit(cert_info, CERT_INFO_ANY_EKU) || GetBit(cert_info, CERT_INFO_NO_EKU))
	{
		name_type_allowed[GEN_EMAIL] = SAN_TYPE_ALLOWED;
		bSanRequired = true;
	}
	if (GetBit(cert_info, CERT_INFO_CLIENT_AUTH))
	{
		/*
		 * DNS and IP address doesn't make sense for a TLS client that
		 * doesn't also do server authentication.
		 */
		if (name_type_allowed[GEN_DNS] == SAN_TYPE_NOT_ALLOWED)
		{
			name_type_allowed[GEN_DNS] = SAN_TYPE_WARN;
			name_type_allowed[GEN_IPADD] = SAN_TYPE_WARN;
		}
		name_type_allowed[GEN_EMAIL] = SAN_TYPE_ALLOWED;
	}
	if (GetBit(warnings, WARN_UNKNOWN_EKU) && !GetBit(cert_info, CERT_INFO_SERV_AUTH) && !GetBit(cert_info, CERT_INFO_ANY_EKU))
	{
		/*
		 * If it's a certificate with an unknown EKU that isn't
		 * also valid for server auth, allow the other types
		 */
		name_type_allowed[GEN_OTHERNAME] = SAN_TYPE_ALLOWED;
		name_type_allowed[GEN_X400] = SAN_TYPE_ALLOWED;
		name_type_allowed[GEN_EDIPARTY] = SAN_TYPE_ALLOWED;
		name_type_allowed[GEN_URI] = SAN_TYPE_ALLOWED;
	}

	X509_NAME *subject = X509_get_subject_name(x509);
	for (int i = 0; i < X509_NAME_entry_count(subject); i++)
	{
		X509_NAME_ENTRY *ne = X509_NAME_get_entry(subject, i);
		ASN1_OBJECT *obj = X509_NAME_ENTRY_get_object(ne);

		if (OBJ_cmp(obj_commonName, obj) == 0)
		{
			commonName = X509_NAME_ENTRY_get_data(ne);
			break;
		}
	}

	do
	{
		int critical = -1;

		GENERAL_NAMES *names = X509_get_ext_d2i(x509, NID_subject_alt_name, &critical, &idx);

		if (names == NULL)
		{
			if (critical >= 0)
			{
				/* Found but fails to parse */
				SetError(ERR_INVALID);
				bSanFound = true;
				continue;
			}
			/* Not found */
			break;
		}
		for (int i = 0; i < sk_GENERAL_NAME_num(names); i++)
		{
			GENERAL_NAME *name = sk_GENERAL_NAME_value(names, i);
			int type;
			ASN1_STRING *name_s = GENERAL_NAME_get0_value(name, &type);
			if (type > GEN_RID || type < 0)
			{
				SetError(ERR_INVALID);
			}
			else if (name_type_allowed[type] == SAN_TYPE_NOT_ALLOWED)
			{
				SetError(ERR_SAN_TYPE);
			}
			else if (name_type_allowed[type] == SAN_TYPE_WARN)
			{
				SetWarning(WARN_TLS_CLIENT_DNS);
			}
			if (type == GEN_DNS)
			{
				for (int j = i+1; j < sk_GENERAL_NAME_num(names); j++)
				{
					GENERAL_NAME *name2 = sk_GENERAL_NAME_value(names, j);
					int type2;
					ASN1_STRING *name2_s = GENERAL_NAME_get0_value(name2, &type2);
					if (type == type2 && ASN1_STRING_cmpcase(name_s, name2_s) == 0)
					{
						SetWarning(WARN_DUPLICATE_SAN);
					}
				}

				char *s = malloc(name_s->length + 1);
				strncpy(s, (char *)name_s->data, name_s->length);
				s[name_s->length] = '\0';

				unsigned char buf[sizeof(struct in6_addr)];
				if (inet_pton(AF_INET, s, buf) == 1 || inet_pton(AF_INET6, s, buf) == 1)
				{
					SetError(ERR_IP_IN_DNSNAME);
				}
				free(s);
			}
			if ((type == GEN_DNS || type == GEN_EMAIL) && commonName != NULL)
			{
				if (ASN1_STRING_cmpcase(name_s, commonName) == 0)
				{
					bCommonNameFound = true;
				}
			}
			if (type == GEN_IPADD)
			{
				int af = AF_UNSPEC;
				if (name_s->length == 4)
				{
					af = AF_INET;
				}
				else if (name_s->length == 16)
				{
					af = AF_INET6;
				}
				else
				{
					SetError(ERR_IP_FAMILY);
				}
				if (af != AF_UNSPEC && commonName != NULL)
				{
					unsigned char buf[sizeof(struct in6_addr)];
					char *s = malloc(commonName->length + 1);

					strncpy(s, (char *)commonName->data, commonName->length);
					s[commonName->length] = '\0';

					inet_pton(af, s, buf);

					/* We want to compare them binary, the string version is not standard. */
					if (memcmp(buf, name_s->data, name_s->length) == 0)
					{
						bCommonNameFound = true;
					}
					free(s);
				}
			}
			CheckGeneralNameType(name);
			bSanName = true;
		}
		sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
		bSanFound = true;
	}
	while (1);

	if (!bSanFound && bSanRequired)
	{
		/* Required by CAB base 7.1.4.2.1 */
		if (type == SubscriberCertificate)
		{
			SetError(ERR_NO_SUBJECT_ALT_NAME);
		}
	}
	if (bSanFound && !bSanName)
	{
		SetError(ERR_SAN_WITHOUT_NAME);
	}
	if (commonName != NULL && bSanFound && !bCommonNameFound)
	{
//		SetError(ERR_CN_NOT_IN_SAN);
	}
}