add altname retrieval from peer cert
This commit is contained in:
parent
45dde2da89
commit
a5af2e3d51
@ -1060,6 +1060,7 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
|
||||
cert->subjectCN = 0;
|
||||
cert->subjectCNLen = 0;
|
||||
cert->subjectCNStored = 0;
|
||||
cert->altNames = NULL;
|
||||
cert->issuer[0] = '\0';
|
||||
cert->subject[0] = '\0';
|
||||
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)
|
||||
{
|
||||
if (cert->subjectCNStored == 1)
|
||||
XFREE(cert->subjectCN, cert->heap, DYNAMIC_TYPE_SUBJECT_CN);
|
||||
if (cert->pubKeyStored == 1)
|
||||
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)
|
||||
{
|
||||
word32 idx = 0;
|
||||
@ -2311,6 +2382,9 @@ static void DecodeCertExtensions(DecodedCert* cert)
|
||||
DecodeAuthInfo(&input[idx], length, cert);
|
||||
break;
|
||||
|
||||
case ALT_NAMES_OID:
|
||||
DecodeAltNames(&input[idx], length, cert);
|
||||
|
||||
default:
|
||||
CYASSL_MSG("\tExtension type not handled, skipping");
|
||||
break;
|
||||
|
@ -61,6 +61,7 @@ enum ASN_Tags {
|
||||
ASN_SEQUENCE = 0x10,
|
||||
ASN_SET = 0x11,
|
||||
ASN_UTC_TIME = 0x17,
|
||||
ASN_DNS_TYPE = 0x02,
|
||||
ASN_GENERALIZED_TIME = 0x18,
|
||||
CRL_EXTENSIONS = 0xa0,
|
||||
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 Signer Signer;
|
||||
|
||||
@ -213,6 +221,7 @@ struct DecodedCert {
|
||||
word32 sigLength; /* length of signature */
|
||||
word32 signatureOID; /* sum of algorithm 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 issuerHash[SHA_SIZE]; /* hash of all Names */
|
||||
#ifdef HAVE_OCSP
|
||||
@ -281,6 +290,7 @@ struct Signer {
|
||||
#define CYASSL_TEST_API CYASSL_LOCAL
|
||||
#endif
|
||||
|
||||
CYASSL_TEST_API void FreeAltNames(DNS_entry*, void*);
|
||||
CYASSL_TEST_API void InitDecodedCert(DecodedCert*, byte*, word32, void*);
|
||||
CYASSL_TEST_API void FreeDecodedCert(DecodedCert*);
|
||||
CYASSL_TEST_API int ParseCert(DecodedCert*, int type, int verify, void* cm);
|
||||
|
@ -209,9 +209,10 @@ enum {
|
||||
DYNAMIC_TYPE_REVOKED = 23,
|
||||
DYNAMIC_TYPE_CRL_ENTRY = 24,
|
||||
DYNAMIC_TYPE_CERT_MANAGER = 25,
|
||||
DYNAMIC_TYPE_CRL_MONITOR = 26,
|
||||
DYNAMIC_TYPE_OCSP_STATUS = 27,
|
||||
DYNAMIC_TYPE_OCSP_ENTRY = 28
|
||||
DYNAMIC_TYPE_CRL_MONITOR = 26,
|
||||
DYNAMIC_TYPE_OCSP_STATUS = 27,
|
||||
DYNAMIC_TYPE_OCSP_ENTRY = 28,
|
||||
DYNAMIC_TYPE_ALTNAME = 29
|
||||
};
|
||||
|
||||
/* stack protection */
|
||||
|
@ -1147,6 +1147,8 @@ struct CYASSL_X509 {
|
||||
byte serial[EXTERNAL_SERIAL_SIZE];
|
||||
char subjectCN[ASN_NAME_MAX]; /* common name short cut */
|
||||
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 char* CyaSSL_X509_get_next_altname(CYASSL_X509*);
|
||||
|
||||
/* connect enough to get peer cert */
|
||||
CYASSL_API int CyaSSL_connect_cert(CYASSL* ssl);
|
||||
|
||||
|
@ -169,6 +169,7 @@ static INLINE void showPeer(CYASSL* ssl)
|
||||
CYASSL_CIPHER* cipher;
|
||||
CYASSL_X509* peer = CyaSSL_get_peer_certificate(ssl);
|
||||
if (peer) {
|
||||
char* altName;
|
||||
char* issuer = CyaSSL_X509_NAME_oneline(
|
||||
CyaSSL_X509_get_issuer_name(peer), 0, 0);
|
||||
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,
|
||||
subject);
|
||||
|
||||
while ( (altName = CyaSSL_X509_get_next_altname(peer)) )
|
||||
printf(" altname = %s\n", altName);
|
||||
|
||||
ret = CyaSSL_X509_get_serial_number(peer, serial, &sz);
|
||||
if (ret == 0) {
|
||||
int i;
|
||||
|
@ -839,7 +839,9 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
||||
ssl->buffers.plainSz = 0;
|
||||
|
||||
#ifdef OPENSSL_EXTRA
|
||||
ssl->peerCert.derCert.buffer = 0;
|
||||
ssl->peerCert.derCert.buffer = NULL;
|
||||
ssl->peerCert.altNames = NULL;
|
||||
ssl->peerCert.altNamesNext = NULL;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
@ -1038,6 +1040,8 @@ void SSL_ResourceFree(CYASSL* ssl)
|
||||
ShrinkOutputBuffer(ssl);
|
||||
#if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS)
|
||||
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);
|
||||
if (ssl->biord != ssl->biowr) /* in case same as write */
|
||||
CyaSSL_BIO_free(ssl->biowr);
|
||||
@ -1845,10 +1849,18 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
||||
/* store cert for potential retrieval */
|
||||
ssl->peerCert.derCert.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
|
||||
DYNAMIC_TYPE_CERT);
|
||||
if (ssl->peerCert.derCert.buffer == NULL)
|
||||
return MEMORY_E;
|
||||
XMEMCPY(ssl->peerCert.derCert.buffer, myCert.buffer, myCert.length);
|
||||
ssl->peerCert.derCert.length = myCert.length;
|
||||
if (ssl->peerCert.derCert.buffer == NULL) {
|
||||
ret = MEMORY_E;
|
||||
fatal = 1;
|
||||
}
|
||||
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
|
||||
|
||||
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_ENTER("X509_get_issuer_name");
|
||||
|
Loading…
Reference in New Issue
Block a user