mirror of https://github.com/wolfSSL/wolfssl.git
add altname retrieval from peer cert
parent
45dde2da89
commit
a5af2e3d51
|
@ -1060,6 +1060,7 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
|
||||||
cert->subjectCN = 0;
|
cert->subjectCN = 0;
|
||||||
cert->subjectCNLen = 0;
|
cert->subjectCNLen = 0;
|
||||||
cert->subjectCNStored = 0;
|
cert->subjectCNStored = 0;
|
||||||
|
cert->altNames = NULL;
|
||||||
cert->issuer[0] = '\0';
|
cert->issuer[0] = '\0';
|
||||||
cert->subject[0] = '\0';
|
cert->subject[0] = '\0';
|
||||||
cert->source = source; /* don't own */
|
cert->source = source; /* don't own */
|
||||||
|
@ -1099,12 +1100,26 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FreeAltNames(DNS_entry* altNames, void* heap)
|
||||||
|
{
|
||||||
|
while (altNames) {
|
||||||
|
DNS_entry* tmp = altNames->next;
|
||||||
|
|
||||||
|
XFREE(altNames->name, heap, DYNAMIC_TYPE_ALTNAME);
|
||||||
|
XFREE(altNames, heap, DYNAMIC_TYPE_ALTNAME);
|
||||||
|
altNames = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void FreeDecodedCert(DecodedCert* cert)
|
void FreeDecodedCert(DecodedCert* cert)
|
||||||
{
|
{
|
||||||
if (cert->subjectCNStored == 1)
|
if (cert->subjectCNStored == 1)
|
||||||
XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
|
XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
|
||||||
if (cert->pubKeyStored == 1)
|
if (cert->pubKeyStored == 1)
|
||||||
XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
XFREE(cert->publicKey, cert->heap, DYNAMIC_TYPE_PUBLIC_KEY);
|
||||||
|
if (cert->altNames)
|
||||||
|
FreeAltNames(cert->altNames, cert->heap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2093,6 +2108,62 @@ static int ConfirmSignature(const byte* buf, word32 bufSz,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void DecodeAltNames(byte* input, int sz, DecodedCert* cert)
|
||||||
|
{
|
||||||
|
word32 idx = 0;
|
||||||
|
int length = 0;
|
||||||
|
|
||||||
|
CYASSL_ENTER("DecodeAltNames");
|
||||||
|
|
||||||
|
if (GetSequence(input, &idx, &length, sz) < 0) {
|
||||||
|
CYASSL_MSG("\tBad Sequence");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (length > 0) {
|
||||||
|
DNS_entry* entry;
|
||||||
|
int strLen;
|
||||||
|
byte b = input[idx++];
|
||||||
|
|
||||||
|
length--;
|
||||||
|
|
||||||
|
if (b != (ASN_CONTEXT_SPECIFIC | ASN_DNS_TYPE)) {
|
||||||
|
CYASSL_MSG("\tNot DNS type");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetLength(input, &idx, &strLen, sz) < 0) {
|
||||||
|
CYASSL_MSG("\tfail: str length");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap,
|
||||||
|
DYNAMIC_TYPE_ALTNAME);
|
||||||
|
if (entry == NULL) {
|
||||||
|
CYASSL_MSG("\tOut of Memory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->name = (char*)XMALLOC(strLen + 1, cert->heap,
|
||||||
|
DYNAMIC_TYPE_ALTNAME);
|
||||||
|
if (entry->name == NULL) {
|
||||||
|
CYASSL_MSG("\tOut of Memory");
|
||||||
|
XFREE(entry, cert->heap, DYNAMIC_TYPE_ALTNAME);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
XMEMCPY(entry->name, &input[idx], strLen);
|
||||||
|
entry->name[strLen] = '\0';
|
||||||
|
|
||||||
|
entry->next = cert->altNames;
|
||||||
|
cert->altNames = entry;
|
||||||
|
|
||||||
|
length -= strLen;
|
||||||
|
idx += strLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
|
static void DecodeBasicCaConstraint(byte* input, int sz, DecodedCert* cert)
|
||||||
{
|
{
|
||||||
word32 idx = 0;
|
word32 idx = 0;
|
||||||
|
@ -2311,6 +2382,9 @@ static void DecodeCertExtensions(DecodedCert* cert)
|
||||||
DecodeAuthInfo(&input[idx], length, cert);
|
DecodeAuthInfo(&input[idx], length, cert);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ALT_NAMES_OID:
|
||||||
|
DecodeAltNames(&input[idx], length, cert);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
CYASSL_MSG("\tExtension type not handled, skipping");
|
CYASSL_MSG("\tExtension type not handled, skipping");
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -61,6 +61,7 @@ enum ASN_Tags {
|
||||||
ASN_SEQUENCE = 0x10,
|
ASN_SEQUENCE = 0x10,
|
||||||
ASN_SET = 0x11,
|
ASN_SET = 0x11,
|
||||||
ASN_UTC_TIME = 0x17,
|
ASN_UTC_TIME = 0x17,
|
||||||
|
ASN_DNS_TYPE = 0x02,
|
||||||
ASN_GENERALIZED_TIME = 0x18,
|
ASN_GENERALIZED_TIME = 0x18,
|
||||||
CRL_EXTENSIONS = 0xa0,
|
CRL_EXTENSIONS = 0xa0,
|
||||||
ASN_EXTENSIONS = 0xa3,
|
ASN_EXTENSIONS = 0xa3,
|
||||||
|
@ -200,6 +201,13 @@ enum VerifyType {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct DNS_entry DNS_entry;
|
||||||
|
|
||||||
|
struct DNS_entry {
|
||||||
|
DNS_entry* next; /* next on DNS list */
|
||||||
|
char* name; /* actual DNS name */
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct DecodedCert DecodedCert;
|
typedef struct DecodedCert DecodedCert;
|
||||||
typedef struct Signer Signer;
|
typedef struct Signer Signer;
|
||||||
|
|
||||||
|
@ -213,6 +221,7 @@ struct DecodedCert {
|
||||||
word32 sigLength; /* length of signature */
|
word32 sigLength; /* length of signature */
|
||||||
word32 signatureOID; /* sum of algorithm object id */
|
word32 signatureOID; /* sum of algorithm object id */
|
||||||
word32 keyOID; /* sum of key algo object id */
|
word32 keyOID; /* sum of key algo object id */
|
||||||
|
DNS_entry* altNames; /* alt names list of dns entries */
|
||||||
byte subjectHash[SHA_SIZE]; /* hash of all Names */
|
byte subjectHash[SHA_SIZE]; /* hash of all Names */
|
||||||
byte issuerHash[SHA_SIZE]; /* hash of all Names */
|
byte issuerHash[SHA_SIZE]; /* hash of all Names */
|
||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
|
@ -281,6 +290,7 @@ struct Signer {
|
||||||
#define CYASSL_TEST_API CYASSL_LOCAL
|
#define CYASSL_TEST_API CYASSL_LOCAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
CYASSL_TEST_API void FreeAltNames(DNS_entry*, void*);
|
||||||
CYASSL_TEST_API void InitDecodedCert(DecodedCert*, byte*, word32, void*);
|
CYASSL_TEST_API void InitDecodedCert(DecodedCert*, byte*, word32, void*);
|
||||||
CYASSL_TEST_API void FreeDecodedCert(DecodedCert*);
|
CYASSL_TEST_API void FreeDecodedCert(DecodedCert*);
|
||||||
CYASSL_TEST_API int ParseCert(DecodedCert*, int type, int verify, void* cm);
|
CYASSL_TEST_API int ParseCert(DecodedCert*, int type, int verify, void* cm);
|
||||||
|
|
|
@ -209,9 +209,10 @@ enum {
|
||||||
DYNAMIC_TYPE_REVOKED = 23,
|
DYNAMIC_TYPE_REVOKED = 23,
|
||||||
DYNAMIC_TYPE_CRL_ENTRY = 24,
|
DYNAMIC_TYPE_CRL_ENTRY = 24,
|
||||||
DYNAMIC_TYPE_CERT_MANAGER = 25,
|
DYNAMIC_TYPE_CERT_MANAGER = 25,
|
||||||
DYNAMIC_TYPE_CRL_MONITOR = 26,
|
DYNAMIC_TYPE_CRL_MONITOR = 26,
|
||||||
DYNAMIC_TYPE_OCSP_STATUS = 27,
|
DYNAMIC_TYPE_OCSP_STATUS = 27,
|
||||||
DYNAMIC_TYPE_OCSP_ENTRY = 28
|
DYNAMIC_TYPE_OCSP_ENTRY = 28,
|
||||||
|
DYNAMIC_TYPE_ALTNAME = 29
|
||||||
};
|
};
|
||||||
|
|
||||||
/* stack protection */
|
/* stack protection */
|
||||||
|
|
|
@ -1147,6 +1147,8 @@ struct CYASSL_X509 {
|
||||||
byte serial[EXTERNAL_SERIAL_SIZE];
|
byte serial[EXTERNAL_SERIAL_SIZE];
|
||||||
char subjectCN[ASN_NAME_MAX]; /* common name short cut */
|
char subjectCN[ASN_NAME_MAX]; /* common name short cut */
|
||||||
buffer derCert; /* may need */
|
buffer derCert; /* may need */
|
||||||
|
DNS_entry* altNames; /* alt names list */
|
||||||
|
DNS_entry* altNamesNext; /* hint for retrieval */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -692,6 +692,8 @@ CYASSL_API const unsigned char* CyaSSL_X509_get_der(CYASSL_X509*, int*);
|
||||||
|
|
||||||
CYASSL_API int CyaSSL_cmp_peer_cert_to_file(CYASSL*, const char*);
|
CYASSL_API int CyaSSL_cmp_peer_cert_to_file(CYASSL*, const char*);
|
||||||
|
|
||||||
|
CYASSL_API char* CyaSSL_X509_get_next_altname(CYASSL_X509*);
|
||||||
|
|
||||||
/* connect enough to get peer cert */
|
/* connect enough to get peer cert */
|
||||||
CYASSL_API int CyaSSL_connect_cert(CYASSL* ssl);
|
CYASSL_API int CyaSSL_connect_cert(CYASSL* ssl);
|
||||||
|
|
||||||
|
|
|
@ -169,6 +169,7 @@ static INLINE void showPeer(CYASSL* ssl)
|
||||||
CYASSL_CIPHER* cipher;
|
CYASSL_CIPHER* cipher;
|
||||||
CYASSL_X509* peer = CyaSSL_get_peer_certificate(ssl);
|
CYASSL_X509* peer = CyaSSL_get_peer_certificate(ssl);
|
||||||
if (peer) {
|
if (peer) {
|
||||||
|
char* altName;
|
||||||
char* issuer = CyaSSL_X509_NAME_oneline(
|
char* issuer = CyaSSL_X509_NAME_oneline(
|
||||||
CyaSSL_X509_get_issuer_name(peer), 0, 0);
|
CyaSSL_X509_get_issuer_name(peer), 0, 0);
|
||||||
char* subject = CyaSSL_X509_NAME_oneline(
|
char* subject = CyaSSL_X509_NAME_oneline(
|
||||||
|
@ -179,6 +180,10 @@ static INLINE void showPeer(CYASSL* ssl)
|
||||||
|
|
||||||
printf("peer's cert info:\n issuer : %s\n subject: %s\n", issuer,
|
printf("peer's cert info:\n issuer : %s\n subject: %s\n", issuer,
|
||||||
subject);
|
subject);
|
||||||
|
|
||||||
|
while ( (altName = CyaSSL_X509_get_next_altname(peer)) )
|
||||||
|
printf(" altname = %s\n", altName);
|
||||||
|
|
||||||
ret = CyaSSL_X509_get_serial_number(peer, serial, &sz);
|
ret = CyaSSL_X509_get_serial_number(peer, serial, &sz);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -839,7 +839,9 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
||||||
ssl->buffers.plainSz = 0;
|
ssl->buffers.plainSz = 0;
|
||||||
|
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
ssl->peerCert.derCert.buffer = 0;
|
ssl->peerCert.derCert.buffer = NULL;
|
||||||
|
ssl->peerCert.altNames = NULL;
|
||||||
|
ssl->peerCert.altNamesNext = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_ECC
|
#ifdef HAVE_ECC
|
||||||
|
@ -1038,6 +1040,8 @@ void SSL_ResourceFree(CYASSL* ssl)
|
||||||
ShrinkOutputBuffer(ssl);
|
ShrinkOutputBuffer(ssl);
|
||||||
#if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
|
#if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
|
||||||
XFREE(ssl->peerCert.derCert.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
|
XFREE(ssl->peerCert.derCert.buffer, ssl->heap, DYNAMIC_TYPE_CERT);
|
||||||
|
if (ssl->peerCert.altNames)
|
||||||
|
FreeAltNames(ssl->peerCert.altNames, ssl->heap);
|
||||||
CyaSSL_BIO_free(ssl->biord);
|
CyaSSL_BIO_free(ssl->biord);
|
||||||
if (ssl->biord != ssl->biowr) /* in case same as write */
|
if (ssl->biord != ssl->biowr) /* in case same as write */
|
||||||
CyaSSL_BIO_free(ssl->biowr);
|
CyaSSL_BIO_free(ssl->biowr);
|
||||||
|
@ -1845,10 +1849,18 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
||||||
/* store cert for potential retrieval */
|
/* store cert for potential retrieval */
|
||||||
ssl->peerCert.derCert.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
|
ssl->peerCert.derCert.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
|
||||||
DYNAMIC_TYPE_CERT);
|
DYNAMIC_TYPE_CERT);
|
||||||
if (ssl->peerCert.derCert.buffer == NULL)
|
if (ssl->peerCert.derCert.buffer == NULL) {
|
||||||
return MEMORY_E;
|
ret = MEMORY_E;
|
||||||
XMEMCPY(ssl->peerCert.derCert.buffer, myCert.buffer, myCert.length);
|
fatal = 1;
|
||||||
ssl->peerCert.derCert.length = myCert.length;
|
}
|
||||||
|
else {
|
||||||
|
XMEMCPY(ssl->peerCert.derCert.buffer, myCert.buffer, myCert.length);
|
||||||
|
ssl->peerCert.derCert.length = myCert.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl->peerCert.altNames = dCert.altNames;
|
||||||
|
dCert.altNames = NULL; /* takes ownership */
|
||||||
|
ssl->peerCert.altNamesNext = ssl->peerCert.altNames; /* index hint */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (fatal) {
|
if (fatal) {
|
||||||
|
|
21
src/ssl.c
21
src/ssl.c
|
@ -3483,6 +3483,27 @@ int CyaSSL_set_compression(CYASSL* ssl)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* return the next, if any, altname from the peer cert */
|
||||||
|
char* CyaSSL_X509_get_next_altname(CYASSL_X509* cert)
|
||||||
|
{
|
||||||
|
char* ret = NULL;
|
||||||
|
CYASSL_ENTER("CyaSSL_X509_get_next_altname");
|
||||||
|
|
||||||
|
/* don't have any to work with */
|
||||||
|
if (cert == NULL || cert->altNames == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* already went through them */
|
||||||
|
if (cert->altNamesNext == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ret = cert->altNamesNext->name;
|
||||||
|
cert->altNamesNext = cert->altNamesNext->next;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CYASSL_X509_NAME* CyaSSL_X509_get_issuer_name(CYASSL_X509* cert)
|
CYASSL_X509_NAME* CyaSSL_X509_get_issuer_name(CYASSL_X509* cert)
|
||||||
{
|
{
|
||||||
CYASSL_ENTER("X509_get_issuer_name");
|
CYASSL_ENTER("X509_get_issuer_name");
|
||||||
|
|
Loading…
Reference in New Issue