mirror of https://github.com/wolfSSL/wolfssl.git
Merge branch 'master' of github.com:cyassl/cyassl
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
|
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 ********************
|
***** To create a dsa cert ********************
|
||||||
|
|
||||||
|
|
|
@ -1218,7 +1218,7 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
|
||||||
cert->extAuthInfoSz = 0;
|
cert->extAuthInfoSz = 0;
|
||||||
cert->extCrlInfo = NULL;
|
cert->extCrlInfo = NULL;
|
||||||
cert->extCrlInfoSz = 0;
|
cert->extCrlInfoSz = 0;
|
||||||
cert->extSubjKeyId = NULL;
|
XMEMSET(cert->extSubjKeyId, 0, SHA_SIZE);
|
||||||
cert->extSubjKeyIdSz = 0;
|
cert->extSubjKeyIdSz = 0;
|
||||||
cert->extAuthKeyId = NULL;
|
cert->extAuthKeyId = NULL;
|
||||||
cert->extAuthKeyIdSz = 0;
|
cert->extAuthKeyIdSz = 0;
|
||||||
|
@ -2591,7 +2591,7 @@ static void DecodeSubjKeyId(byte* input, int sz, DecodedCert* cert)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cert->extSubjKeyId = input + idx;
|
XMEMCPY(cert->extSubjKeyId, input + idx, length);
|
||||||
cert->extSubjKeyIdSz = length;
|
cert->extSubjKeyIdSz = length;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -2723,6 +2723,9 @@ int ParseCert(DecodedCert* cert, int type, int verify, void* cm)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
CYASSL_LOCAL Signer* GetCA(void* signers, byte* hash);
|
CYASSL_LOCAL Signer* GetCA(void* signers, byte* hash);
|
||||||
|
#ifndef NO_SKID
|
||||||
|
CYASSL_LOCAL Signer* GetCAByName(void* signers, byte* hash);
|
||||||
|
#endif
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -2763,8 +2766,26 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
|
||||||
if (confirmOID != cert->signatureOID)
|
if (confirmOID != cert->signatureOID)
|
||||||
return ASN_SIG_OID_E;
|
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) {
|
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");
|
CYASSL_MSG("About to verify certificate signature");
|
||||||
|
|
||||||
if (ca) {
|
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)
|
if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
|
||||||
return ASN_PARSE_E;
|
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");
|
CYASSL_MSG("About to verify CRL signature");
|
||||||
|
|
||||||
if (ca) {
|
if (ca) {
|
||||||
|
|
|
@ -251,7 +251,7 @@ struct DecodedCert {
|
||||||
int extAuthInfoSz; /* length of the URI */
|
int extAuthInfoSz; /* length of the URI */
|
||||||
byte* extCrlInfo; /* CRL Distribution Points */
|
byte* extCrlInfo; /* CRL Distribution Points */
|
||||||
int extCrlInfoSz; /* length of the URI */
|
int extCrlInfoSz; /* length of the URI */
|
||||||
byte* extSubjKeyId; /* Subject Key ID */
|
byte extSubjKeyId[SHA_SIZE]; /* Subject Key ID */
|
||||||
int extSubjKeyIdSz; /* length of the ID */
|
int extSubjKeyIdSz; /* length of the ID */
|
||||||
byte* extAuthKeyId; /* Authority Key ID */
|
byte* extAuthKeyId; /* Authority Key ID */
|
||||||
int extAuthKeyIdSz; /* length of the ID */
|
int extAuthKeyIdSz; /* length of the ID */
|
||||||
|
@ -291,7 +291,12 @@ struct Signer {
|
||||||
word32 pubKeySize;
|
word32 pubKeySize;
|
||||||
word32 keyOID; /* key type */
|
word32 keyOID; /* key type */
|
||||||
char* name; /* common name */
|
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;
|
Signer* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1845,6 +1845,9 @@ CYASSL_LOCAL void ShrinkInputBuffer(CYASSL* ssl, int forcedFree);
|
||||||
CYASSL_LOCAL void ShrinkOutputBuffer(CYASSL* ssl);
|
CYASSL_LOCAL void ShrinkOutputBuffer(CYASSL* ssl);
|
||||||
#ifndef NO_CERTS
|
#ifndef NO_CERTS
|
||||||
CYASSL_LOCAL Signer* GetCA(void* cm, byte* hash);
|
CYASSL_LOCAL Signer* GetCA(void* cm, byte* hash);
|
||||||
|
#ifndef NO_SKID
|
||||||
|
CYASSL_LOCAL Signer* GetCAByName(void* cm, byte* hash);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
CYASSL_LOCAL void BuildTlsFinished(CYASSL* ssl, Hashes* hashes,
|
CYASSL_LOCAL void BuildTlsFinished(CYASSL* ssl, Hashes* hashes,
|
||||||
const byte* sender);
|
const byte* sender);
|
||||||
|
|
|
@ -2931,17 +2931,24 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
||||||
while (count > 1) {
|
while (count > 1) {
|
||||||
buffer myCert = certs[count - 1];
|
buffer myCert = certs[count - 1];
|
||||||
DecodedCert dCert;
|
DecodedCert dCert;
|
||||||
|
byte* subjectHash;
|
||||||
|
|
||||||
InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
|
InitDecodedCert(&dCert, myCert.buffer, myCert.length, ssl->heap);
|
||||||
ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
|
ret = ParseCertRelative(&dCert, CERT_TYPE, !ssl->options.verifyNone,
|
||||||
ssl->ctx->cm);
|
ssl->ctx->cm);
|
||||||
|
#ifndef NO_SKID
|
||||||
|
subjectHash = dCert.extSubjKeyId;
|
||||||
|
#else
|
||||||
|
subjectHash = dCert.subjectHash;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ret == 0 && dCert.isCA == 0) {
|
if (ret == 0 && dCert.isCA == 0) {
|
||||||
CYASSL_MSG("Chain cert is not a CA, not adding as one");
|
CYASSL_MSG("Chain cert is not a CA, not adding as one");
|
||||||
}
|
}
|
||||||
else if (ret == 0 && ssl->options.verifyNone) {
|
else if (ret == 0 && ssl->options.verifyNone) {
|
||||||
CYASSL_MSG("Chain cert not verified by option, not adding as CA");
|
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;
|
buffer add;
|
||||||
add.length = myCert.length;
|
add.length = myCert.length;
|
||||||
add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
|
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;
|
return ret;
|
||||||
signers = cm->caTable[row];
|
signers = cm->caTable[row];
|
||||||
while (signers) {
|
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;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -908,7 +914,13 @@ Signer* GetCA(void* vp, byte* hash)
|
||||||
|
|
||||||
signers = cm->caTable[row];
|
signers = cm->caTable[row];
|
||||||
while (signers) {
|
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;
|
ret = signers;
|
||||||
break;
|
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 */
|
/* owns der, internal now uses too */
|
||||||
/* type flag ids from user or from chain received during verify
|
/* type flag ids from user or from chain received during verify
|
||||||
don't allow chain ones to be added w/o isCA extension */
|
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;
|
DecodedCert cert;
|
||||||
Signer* signer = 0;
|
Signer* signer = 0;
|
||||||
word32 row;
|
word32 row;
|
||||||
|
byte* subjectHash;
|
||||||
|
|
||||||
CYASSL_MSG("Adding a CA");
|
CYASSL_MSG("Adding a CA");
|
||||||
InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
|
InitDecodedCert(&cert, der.buffer, der.length, cm->heap);
|
||||||
ret = ParseCert(&cert, CA_TYPE, verify, cm);
|
ret = ParseCert(&cert, CA_TYPE, verify, cm);
|
||||||
CYASSL_MSG(" Parsed new CA");
|
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) {
|
if (ret == 0 && cert.isCA == 0 && type != CYASSL_USER_CA) {
|
||||||
CYASSL_MSG(" Can't add as CA if not actually one");
|
CYASSL_MSG(" Can't add as CA if not actually one");
|
||||||
ret = NOT_CA_ERROR;
|
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");
|
CYASSL_MSG(" Already have this CA, not adding again");
|
||||||
(void)ret;
|
(void)ret;
|
||||||
}
|
}
|
||||||
|
@ -953,13 +1003,21 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify)
|
||||||
signer->publicKey = cert.publicKey;
|
signer->publicKey = cert.publicKey;
|
||||||
signer->pubKeySize = cert.pubKeySize;
|
signer->pubKeySize = cert.pubKeySize;
|
||||||
signer->name = cert.subjectCN;
|
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 */
|
signer->next = NULL; /* in case lock fails */
|
||||||
|
|
||||||
cert.publicKey = 0; /* don't free here */
|
cert.publicKey = 0; /* don't free here */
|
||||||
cert.subjectCN = 0;
|
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) {
|
if (LockMutex(&cm->caLock) == 0) {
|
||||||
signer->next = cm->caTable[row];
|
signer->next = cm->caTable[row];
|
||||||
|
|
Loading…
Reference in New Issue