Esempio n. 1
0
int X509_check_issued(X509 *issuer, X509 *subject)
{
	if(X509_NAME_cmp(X509_get_subject_name(issuer),
			X509_get_issuer_name(subject)))
				return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
	x509v3_cache_extensions(issuer);
	x509v3_cache_extensions(subject);

	if(subject->akid)
		{
		int ret = X509_check_akid(issuer, subject->akid);
		if (ret != X509_V_OK)
			return ret;
		}

	if(subject->ex_flags & EXFLAG_PROXY)
		{
		if(ku_reject(issuer, KU_DIGITAL_SIGNATURE))
			return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
		}
	else if(ku_reject(issuer, KU_KEY_CERT_SIGN) &&
            // [MS_CHANGE] Enable Windows self signed certs to pass validation
            (0 != X509_NAME_cmp(X509_get_subject_name(subject),
                                 X509_get_issuer_name(subject))))
		{
		return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
		}
	return X509_V_OK;
}
Esempio n. 2
0
int X509_check_issued(X509 *issuer, X509 *subject)
{
  if(X509_NAME_cmp(X509_get_subject_name(issuer),
      X509_get_issuer_name(subject)))
        return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
  x509v3_cache_extensions(issuer);
  x509v3_cache_extensions(subject);
  if(subject->akid) {
    /* Check key ids (if present) */
    if(subject->akid->keyid && issuer->skid &&
     ASN1_OCTET_STRING_cmp(subject->akid->keyid, issuer->skid) )
        return X509_V_ERR_AKID_SKID_MISMATCH;
    /* Check serial number */
    if(subject->akid->serial &&
      ASN1_INTEGER_cmp(X509_get_serialNumber(issuer),
            subject->akid->serial))
        return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
    /* Check issuer name */
    if(subject->akid->issuer) {
      /* Ugh, for some peculiar reason AKID includes
       * SEQUENCE OF GeneralName. So look for a DirName.
       * There may be more than one but we only take any
       * notice of the first.
       */
      GENERAL_NAMES *gens;
      GENERAL_NAME *gen;
      X509_NAME *nm = NULL;
      int i;
      gens = subject->akid->issuer;
      for(i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
        gen = sk_GENERAL_NAME_value(gens, i);
        if(gen->type == GEN_DIRNAME) {
          nm = gen->d.dirn;
          break;
        }
      }
      if(nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
        return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
    }
  }
  if(subject->ex_flags & EXFLAG_PROXY)
    {
    if(ku_reject(issuer, KU_DIGITAL_SIGNATURE))
      return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
    }
  else if(ku_reject(issuer, KU_KEY_CERT_SIGN))
    return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
  return X509_V_OK;
}
Esempio n. 3
0
static int check_ca(const X509 *x)
{
    /* keyUsage if present should allow cert signing */
    if (ku_reject(x, KU_KEY_CERT_SIGN))
        return 0;
    if (x->ex_flags & EXFLAG_BCONS) {
        if (x->ex_flags & EXFLAG_CA)
            return 1;
        /* If basicConstraints says not a CA then say so */
        else
            return 0;
    } else {
        /* we support V1 roots for...  uh, I don't really know why. */
        if ((x->ex_flags & V1_ROOT) == V1_ROOT)
            return 3;
        /*
         * If key usage present it must have certSign so tolerate it
         */
        else if (x->ex_flags & EXFLAG_KUSAGE)
            return 4;
        /* Older certificates could have Netscape-specific CA types */
        else if (x->ex_flags & EXFLAG_NSCERT && x->ex_nscert & NS_ANY_CA)
            return 5;
        /* can this still be regarded a CA certificate?  I doubt it */
        return 0;
    }
}
Esempio n. 4
0
static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, int ca)
{
  int ret;
  ret = purpose_smime(x, ca);
  if(!ret || ca) return ret;
  if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
  return ret;
}
Esempio n. 5
0
static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
{
  int ret;
  ret = purpose_smime(x, ca);
  if(!ret || ca) return ret;
  if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_NON_REPUDIATION)) return 0;
  return ret;
}
Esempio n. 6
0
static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
{
  int ret;
  ret = check_purpose_ssl_server(xp, x, ca);
  if(!ret || ca) return ret;
  /* We need to encipher or Netscape complains */
  if(ku_reject(x, KU_KEY_ENCIPHERMENT)) return 0;
  return ret;
}
Esempio n. 7
0
static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca)
{
  if(ca) {
    int ca_ret;
    if((ca_ret = check_ca(x)) != 2) return ca_ret;
    else return 0;
  }
  if(ku_reject(x, KU_CRL_SIGN)) return 0;
  return 1;
}
Esempio n. 8
0
static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca)
{
  if(xku_reject(x,XKU_SSL_CLIENT)) return 0;
  if(ca) return check_ssl_ca(x);
  /* We need to do digital signatures with it */
  if(ku_reject(x,KU_DIGITAL_SIGNATURE)) return 0;
  /* nsCertType if present should allow SSL client use */  
  if(ns_reject(x, NS_SSL_CLIENT)) return 0;
  return 1;
}
Esempio n. 9
0
static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
{
	if(xku_reject(x,XKU_SSL_SERVER|XKU_SGC)) return 0;
	if(ca) return check_ssl_ca(x);

	if(ns_reject(x, NS_SSL_SERVER)) return 0;
	if(ku_reject(x, KU_TLS)) return 0;
	
	return 1;

}
Esempio n. 10
0
static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, int ca)
{
  if(xku_reject(x,XKU_SSL_SERVER|XKU_SGC)) return 0;
  if(ca) return check_ssl_ca(x);

  if(ns_reject(x, NS_SSL_SERVER)) return 0;
  /* Now as for keyUsage: we'll at least need to sign OR encipher */
  if(ku_reject(x, KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT)) return 0;
  
  return 1;

}
Esempio n. 11
0
int X509_check_issued(X509 *issuer, X509 *subject)
{
    if (X509_NAME_cmp(X509_get_subject_name(issuer),
                      X509_get_issuer_name(subject)))
        return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
    x509v3_cache_extensions(issuer);
    x509v3_cache_extensions(subject);

    if (subject->akid) {
        int ret = X509_check_akid(issuer, subject->akid);
        if (ret != X509_V_OK)
            return ret;
    }

    if (subject->ex_flags & EXFLAG_PROXY) {
        if (ku_reject(issuer, KU_DIGITAL_SIGNATURE))
            return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
    } else if (ku_reject(issuer, KU_KEY_CERT_SIGN))
        return X509_V_ERR_KEYUSAGE_NO_CERTSIGN;
    return X509_V_OK;
}
Esempio n. 12
0
static int ca_check(const X509 *x)
{
	/* keyUsage if present should allow cert signing */
	if(ku_reject(x, KU_KEY_CERT_SIGN)) return 0;
	if(x->ex_flags & EXFLAG_BCONS) {
		if(x->ex_flags & EXFLAG_CA) return 1;
		/* If basicConstraints says not a CA then say so */
		else return 0;
	} else {
		if((x->ex_flags & V1_ROOT) == V1_ROOT) return 3;
		/* If key usage present it must have certSign so tolerate it */
		else if (x->ex_flags & EXFLAG_KUSAGE) return 3;
		else return 2;
	}
}
Esempio n. 13
0
static void x509v3_cache_extensions(X509 *x)
{
    BASIC_CONSTRAINTS *bs;
    PROXY_CERT_INFO_EXTENSION *pci;
    ASN1_BIT_STRING *usage;
    ASN1_BIT_STRING *ns;
    EXTENDED_KEY_USAGE *extusage;
    X509_EXTENSION *ex;

    int i;
    if (x->ex_flags & EXFLAG_SET)
        return;
    X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
    /* V1 should mean no extensions ... */
    if (!X509_get_version(x))
        x->ex_flags |= EXFLAG_V1;
    /* Handle basic constraints */
    if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
        if (bs->ca)
            x->ex_flags |= EXFLAG_CA;
        if (bs->pathlen) {
            if ((bs->pathlen->type == V_ASN1_NEG_INTEGER)
                || !bs->ca) {
                x->ex_flags |= EXFLAG_INVALID;
                x->ex_pathlen = 0;
            } else
                x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen);
        } else
            x->ex_pathlen = -1;
        BASIC_CONSTRAINTS_free(bs);
        x->ex_flags |= EXFLAG_BCONS;
    }
    /* Handle proxy certificates */
    if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
        if (x->ex_flags & EXFLAG_CA
            || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0
            || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) {
            x->ex_flags |= EXFLAG_INVALID;
        }
        if (pci->pcPathLengthConstraint) {
            x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint);
        } else
            x->ex_pcpathlen = -1;
        PROXY_CERT_INFO_EXTENSION_free(pci);
        x->ex_flags |= EXFLAG_PROXY;
    }
    /* Handle key usage */
    if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
        if (usage->length > 0) {
            x->ex_kusage = usage->data[0];
            if (usage->length > 1)
                x->ex_kusage |= usage->data[1] << 8;
        } else
            x->ex_kusage = 0;
        x->ex_flags |= EXFLAG_KUSAGE;
        ASN1_BIT_STRING_free(usage);
    }
    x->ex_xkusage = 0;
    if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) {
        x->ex_flags |= EXFLAG_XKUSAGE;
        for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) {
            switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) {
            case NID_server_auth:
                x->ex_xkusage |= XKU_SSL_SERVER;
                break;

            case NID_client_auth:
                x->ex_xkusage |= XKU_SSL_CLIENT;
                break;

            case NID_email_protect:
                x->ex_xkusage |= XKU_SMIME;
                break;

            case NID_code_sign:
                x->ex_xkusage |= XKU_CODE_SIGN;
                break;

            case NID_ms_sgc:
            case NID_ns_sgc:
                x->ex_xkusage |= XKU_SGC;
                break;

            case NID_OCSP_sign:
                x->ex_xkusage |= XKU_OCSP_SIGN;
                break;

            case NID_time_stamp:
                x->ex_xkusage |= XKU_TIMESTAMP;
                break;

            case NID_dvcs:
                x->ex_xkusage |= XKU_DVCS;
                break;

            case NID_anyExtendedKeyUsage:
                x->ex_xkusage |= XKU_ANYEKU;
                break;
            }
        }
        sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free);
    }

    if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) {
        if (ns->length > 0)
            x->ex_nscert = ns->data[0];
        else
            x->ex_nscert = 0;
        x->ex_flags |= EXFLAG_NSCERT;
        ASN1_BIT_STRING_free(ns);
    }
    x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
    x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
    /* Does subject name match issuer ? */
    if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
        x->ex_flags |= EXFLAG_SI;
        /* If SKID matches AKID also indicate self signed */
        if (X509_check_akid(x, x->akid) == X509_V_OK &&
            !ku_reject(x, KU_KEY_CERT_SIGN))
            x->ex_flags |= EXFLAG_SS;
    }
    x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
    x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
    if (!x->nc && (i != -1))
        x->ex_flags |= EXFLAG_INVALID;
    setup_crldp(x);

#ifndef OPENSSL_NO_RFC3779
    x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL);
    x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum,
                                       NULL, NULL);
#endif
    for (i = 0; i < X509_get_ext_count(x); i++) {
        ex = X509_get_ext(x, i);
        if (OBJ_obj2nid(X509_EXTENSION_get_object(ex))
            == NID_freshest_crl)
            x->ex_flags |= EXFLAG_FRESHEST;
        if (!X509_EXTENSION_get_critical(ex))
            continue;
        if (!X509_supported_extension(ex)) {
            x->ex_flags |= EXFLAG_CRITICAL;
            break;
        }
    }
    x->ex_flags |= EXFLAG_SET;
}