Added checking of the key usage and extended key usage extensions in the

certificates.
This commit is contained in:
John Safranek 2014-04-10 16:50:14 -07:00
parent 1f3bc9263d
commit e79ce42ef4
5 changed files with 72 additions and 0 deletions

View File

@ -6493,6 +6493,12 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
if (ca) {
CYASSL_MSG("Found CRL issuer CA");
/* try to confirm/verify signature */
#ifndef IGNORE_KEY_EXTENSIONS
if ((ca->keyUsage & KEYUSE_CRL_SIGN) == 0) {
CYASSL_MSG("CA cannot sign CRLs");
return ASN_CRL_NO_SIGNER_E;
}
#endif /* IGNORE_KEY_EXTENSIONS */
if (!ConfirmSignature(buff + dcrl->certBegin,
dcrl->sigIndex - dcrl->certBegin,
ca->publicKey, ca->pubKeySize, ca->keyOID,

View File

@ -426,6 +426,7 @@ struct DecodedCert {
struct Signer {
word32 pubKeySize;
word32 keyOID; /* key type */
word16 keyUsage;
byte* publicKey;
int nameLen;
char* name; /* common name */

View File

@ -115,6 +115,10 @@ enum CyaSSL_ErrorCodes {
UNKNOWN_SNI_HOST_NAME_E = -281, /* Unrecognized host name Error */
UNKNOWN_MAX_FRAG_LEN_E = -282, /* Unrecognized max frag len Error */
/* add strings to SetErrorString !!!!! */
KEYUSE_SIGNATURE_E = -283, /* KeyUse digSignature error */
KEYUSE_AGREEMENT_E = -284, /* KeyUse keyAgreement error */
KEYUSE_ENCIPHER_E = -285, /* KeyUse keyEncipher error */
EXTKEYUSE_AUTH_E = -286, /* ExtKeyUse server|client_auth */
/* begin negotiation parameter errors */
UNSUPPORTED_SUITE = -290, /* unsupported cipher suite */

View File

@ -3465,6 +3465,49 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx,
}
#endif
#ifndef IGNORE_KEY_EXTENSIONS
if (dCert.extKeyUsageSet) {
if ((ssl->specs.kea == rsa_kea) &&
(dCert.extKeyUsage & KEYUSE_KEY_ENCIPHER) == 0) {
fatal = 1;
ret = KEYUSE_ENCIPHER_E;
}
if ((ssl->specs.kea == diffie_hellman_kea ||
ssl->specs.kea == ecc_diffie_hellman_kea ||
ssl->specs.kea == ecc_static_diffie_hellman_kea) &&
(dCert.extKeyUsage & KEYUSE_KEY_AGREE) == 0) {
fatal = 1;
ret = KEYUSE_AGREEMENT_E;
}
if ((ssl->specs.sig_algo == rsa_sa_algo ||
ssl->specs.sig_algo == ecc_dsa_sa_algo) &&
(dCert.extKeyUsage & KEYUSE_DIGITAL_SIG) == 0) {
CYASSL_MSG("KeyUse Digital Sig not set");
fatal = 1;
ret = KEYUSE_SIGNATURE_E;
}
}
if (dCert.extExtKeyUsageSet) {
if (ssl->options.side == CYASSL_CLIENT_END) {
if ((dCert.extExtKeyUsage &
(EXTKEYUSE_ANY | EXTKEYUSE_SERVER_AUTH)) == 0) {
CYASSL_MSG("ExtKeyUse Server Auth not set");
fatal = 1;
ret = EXTKEYUSE_AUTH_E;
}
}
else {
if ((dCert.extExtKeyUsage &
(EXTKEYUSE_ANY | EXTKEYUSE_CLIENT_AUTH)) == 0) {
CYASSL_MSG("ExtKeyUse Client Auth not set");
fatal = 1;
ret = EXTKEYUSE_AUTH_E;
}
}
}
#endif /* IGNORE_KEY_EXTENSIONS */
if (fatal) {
FreeDecodedCert(&dCert);
ssl->error = ret;
@ -6451,6 +6494,22 @@ void SetErrorString(int error, char* str)
XSTRNCPY(str, "Unrecognized host name Error", max);
break;
case KEYUSE_SIGNATURE_E:
XSTRNCPY(str, "Key Use digitalSignature not set Error", max);
break;
case KEYUSE_AGREEMENT_E:
XSTRNCPY(str, "Key Use keyAgreement not set Error", max);
break;
case KEYUSE_ENCIPHER_E:
XSTRNCPY(str, "Key Use keyEncipherment not set Error", max);
break;
case EXTKEYUSE_AUTH_E:
XSTRNCPY(str, "Ext Key Use server/client auth not set Error", max);
break;
default :
XSTRNCPY(str, "unknown error number", max);
}

View File

@ -1526,6 +1526,8 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
cert.extSubjKeyId, SHA_DIGEST_SIZE);
#endif
XMEMCPY(signer->subjectNameHash, cert.subjectHash, SHA_DIGEST_SIZE);
signer->keyUsage = cert.extKeyUsageSet ? cert.extKeyUsage : 0xFFFF;
/* If Key Usage not set, all uses valid. */
signer->next = NULL; /* in case lock fails */
cert.publicKey = 0; /* don't free here */