Merge branch 'master' of github.com:cyassl/cyassl
This commit is contained in:
commit
5a1886656a
@ -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 ********************
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
68
src/ssl.c
68
src/ssl.c
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user