Merge branch 'master' of github.com:cyassl/cyassl

pull/1/head
toddouska 2013-04-29 14:23:22 -07:00
commit 5a1886656a
6 changed files with 129 additions and 12 deletions

View File

@ -30,6 +30,22 @@ same as self signed, use ca prefix instead of client
3) openssl x509 -req -in server-req.pem -days 1000 -md5 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem
***** Adding Subject Key ID and Authentication Key ID extensions to a cert *****
Create a config file for OpenSSL with the example contents:
[skidakid]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid
Add to the openssl command for creating a cert signed by a CA step 3 the
following options:
-extfile <file.cnf> -extensions skidakid
anywhere before the redirect. This will add the cert's public key hash as the
Subject Key Identifier, and the signer's SKID as the Authentication Key ID.
***** To create a dsa cert ********************

View File

@ -1218,7 +1218,7 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
cert->extAuthInfoSz = 0;
cert->extCrlInfo = NULL;
cert->extCrlInfoSz = 0;
cert->extSubjKeyId = NULL;
XMEMSET(cert->extSubjKeyId, 0, SHA_SIZE);
cert->extSubjKeyIdSz = 0;
cert->extAuthKeyId = NULL;
cert->extAuthKeyIdSz = 0;
@ -2591,7 +2591,7 @@ static void DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
return;
}
cert->extSubjKeyId = input + idx;
XMEMCPY(cert->extSubjKeyId, input + idx, length);
cert->extSubjKeyIdSz = length;
return;
@ -2723,6 +2723,9 @@ int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
extern "C" {
#endif
CYASSL_LOCAL Signer* GetCA(void* signers, byte* hash);
#ifndef NO_SKID
CYASSL_LOCAL Signer* GetCAByName(void* signers, byte* hash);
#endif
#ifdef __cplusplus
}
#endif
@ -2763,8 +2766,26 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
if (confirmOID != cert->signatureOID)
return ASN_SIG_OID_E;
#ifndef NO_SKID
if (cert->extSubjKeyIdSz == 0) {
Sha sha;
InitSha(&sha);
ShaUpdate(&sha, cert->publicKey, cert->pubKeySize);
ShaFinal(&sha, cert->extSubjKeyId);
cert->extSubjKeyIdSz = SHA_SIZE;
}
#endif
if (verify && type != CA_TYPE) {
Signer* ca = GetCA(cm, cert->issuerHash);
Signer* ca;
#ifndef NO_SKID
if (cert->extAuthKeyId != NULL)
ca = GetCA(cm, cert->extAuthKeyId);
else
ca = GetCAByName(cm, cert->issuerHash);
#else /* NO_SKID */
ca = GetCA(cm, cert->issuerHash);
#endif /* NO SKID */
CYASSL_MSG("About to verify certificate signature");
if (ca) {
@ -5235,7 +5256,14 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, word32 sz, void* cm)
if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
return ASN_PARSE_E;
ca = GetCA(cm, dcrl->issuerHash);
#ifndef NO_SKID
if (dcrl->extAuthKeyId != NULL)
ca = GetCA(cm, dcrl->extAuthKeyId);
else
ca = GetCAByName(cm, dcrl->issuerHash);
#else /* NO_SKID */
ca = GetCA(cm, dcrl->issuerHash);
#endif /* NO_SKID */
CYASSL_MSG("About to verify CRL signature");
if (ca) {

View File

@ -251,7 +251,7 @@ struct DecodedCert {
int extAuthInfoSz; /* length of the URI */
byte* extCrlInfo; /* CRL Distribution Points */
int extCrlInfoSz; /* length of the URI */
byte* extSubjKeyId; /* Subject Key ID */
byte extSubjKeyId[SHA_SIZE]; /* Subject Key ID */
int extSubjKeyIdSz; /* length of the ID */
byte* extAuthKeyId; /* Authority Key ID */
int extAuthKeyIdSz; /* length of the ID */
@ -291,7 +291,12 @@ struct Signer {
word32 pubKeySize;
word32 keyOID; /* key type */
char* name; /* common name */
byte hash[SIGNER_DIGEST_SIZE];/* sha hash of names in certificate */
byte subjectNameHash[SIGNER_DIGEST_SIZE];
/* sha hash of names in certificate */
#ifndef NO_SKID
byte subjectKeyIdHash[SIGNER_DIGEST_SIZE];
/* sha hash of names in certificate */
#endif
Signer* next;
};

View File

@ -1845,6 +1845,9 @@ CYASSL_LOCAL void ShrinkInputBuffer(CYASSL* ssl, int forcedFree);
CYASSL_LOCAL void ShrinkOutputBuffer(CYASSL* ssl);
#ifndef NO_CERTS
CYASSL_LOCAL Signer* GetCA(void* cm, byte* hash);
#ifndef NO_SKID
CYASSL_LOCAL Signer* GetCAByName(void* cm, byte* hash);
#endif
#endif
CYASSL_LOCAL void BuildTlsFinished(CYASSL* ssl, Hashes* hashes,
const byte* sender);

View File

@ -2931,17 +2931,24 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
while (count > 1) {
buffer myCert = certs[count - 1];
DecodedCert dCert;
byte* subjectHash;
InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
ssl->ctx->cm);
#ifndef NO_SKID
subjectHash = dCert.extSubjKeyId;
#else
subjectHash = dCert.subjectHash;
#endif
if (ret == 0 && dCert.isCA == 0) {
CYASSL_MSG("Chain cert is not a CA, not adding as one");
}
else if (ret == 0 && ssl->options.verifyNone) {
CYASSL_MSG("Chain cert not verified by option, not adding as CA");
}
else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, dCert.subjectHash)) {
else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, subjectHash)) {
buffer add;
add.length = myCert.length;
add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,

View File

@ -880,7 +880,13 @@ int AlreadySigner(CYASSL_CERT_MANAGER* cm, byte* hash)
return ret;
signers = cm->caTable[row];
while (signers) {
if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
byte* subjectHash;
#ifndef NO_SKID
subjectHash = signers->subjectKeyIdHash;
#else
subjectHash = signers->subjectNameHash;
#endif
if (XMEMCMP(hash, subjectHash, SHA_DIGEST_SIZE) == 0) {
ret = 1;
break;
}
@ -908,7 +914,13 @@ Signer* GetCA(void* vp, byte* hash)
signers = cm->caTable[row];
while (signers) {
if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
byte* subjectHash;
#ifndef NO_SKID
subjectHash = signers->subjectKeyIdHash;
#else
subjectHash = signers->subjectNameHash;
#endif
if (XMEMCMP(hash, subjectHash, SHA_DIGEST_SIZE) == 0) {
ret = signers;
break;
}
@ -920,6 +932,37 @@ Signer* GetCA(void* vp, byte* hash)
}
#ifndef NO_SKID
/* return CA if found, otherwise NULL. Walk through hash table. */
Signer* GetCAByName(void* vp, byte* hash)
{
CYASSL_CERT_MANAGER* cm = (CYASSL_CERT_MANAGER*)vp;
Signer* ret = NULL;
Signer* signers;
word32 row;
if (cm == NULL)
return NULL;
if (LockMutex(&cm->caLock) != 0)
return ret;
for (row = 0; row < CA_TABLE_SIZE && ret == NULL; row++) {
signers = cm->caTable[row];
while (signers && ret == NULL) {
if (XMEMCMP(hash, signers->subjectNameHash, SHA_DIGEST_SIZE) == 0) {
ret = signers;
}
signers = signers->next;
}
}
UnLockMutex(&cm->caLock);
return ret;
}
#endif
/* owns der, internal now uses too */
/* type flag ids from user or from chain received during verify
don't allow chain ones to be added w/o isCA extension */
@ -929,17 +972,24 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
DecodedCert cert;
Signer* signer = 0;
word32 row;
byte* subjectHash;
CYASSL_MSG("Adding a CA");
InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
ret = ParseCert(&cert, CA_TYPE, verify, cm);
CYASSL_MSG(" Parsed new CA");
#ifndef NO_SKID
subjectHash = cert.extSubjKeyId;
#else
subjectHash = cert.subjectHash;
#endif
if (ret == 0 && cert.isCA == 0 && type != CYASSL_USER_CA) {
CYASSL_MSG(" Can't add as CA if not actually one");
ret = NOT_CA_ERROR;
}
else if (ret == 0 && AlreadySigner(cm, cert.subjectHash)) {
else if (ret == 0 && AlreadySigner(cm, subjectHash)) {
CYASSL_MSG(" Already have this CA, not adding again");
(void)ret;
}
@ -953,13 +1003,21 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
signer->publicKey = cert.publicKey;
signer->pubKeySize = cert.pubKeySize;
signer->name = cert.subjectCN;
XMEMCPY(signer->hash, cert.subjectHash, SHA_DIGEST_SIZE);
#ifndef NO_SKID
XMEMCPY(signer->subjectKeyIdHash,
cert.extSubjKeyId, SHA_DIGEST_SIZE);
#endif
XMEMCPY(signer->subjectNameHash, cert.subjectHash, SHA_DIGEST_SIZE);
signer->next = NULL; /* in case lock fails */
cert.publicKey = 0; /* don't free here */
cert.subjectCN = 0;
row = HashSigner(signer->hash);
#ifndef NO_SKID
row = HashSigner(signer->subjectKeyIdHash);
#else
row = HashSigner(signer->subjectNameHash);
#endif
if (LockMutex(&cm->caLock) == 0) {
signer->next = cm->caTable[row];