X.509 Additions:

* CyaSSL_X509_d2i()
* CyaSSL_X509_d2i_fp()
* CyaSSL_X509_version()
* CyaSSL_X509_get_notBefore()
* CyaSSL_X509_get_notAfter()
* CyaSSL_X509_STORE_new()
* CyaSSL_X509_STORE_free()
* CyaSSL_X509_STORE_add_cert()
* CyaSSL_X509_STORE_set_default_paths()
* CyaSSL_X509_get_pubkey()
* CyaSSL_EVP_PKEY_free()
* CyaSSL_X509_NAME_get_text_by_NID()
* CyaSSL_X509_NAME_entry_count()
* CyaSSL_X509_verify_cert()
* CyaSSL_X509_STORE_CTX_new()
* CyaSSL_X509_STORE_CTX_init()
* CyaSSL_X509_STORE_CTX_free()
This commit is contained in:
John Safranek 2013-10-17 14:31:20 -07:00
parent 5e00d62ea3
commit 913e200cd0
6 changed files with 693 additions and 72 deletions

View File

@ -1250,6 +1250,7 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
cert->publicKey = 0;
cert->pubKeySize = 0;
cert->pubKeyStored = 0;
cert->version = 0;
cert->signature = 0;
cert->subjectCN = 0;
cert->subjectCNLen = 0;
@ -1290,11 +1291,15 @@ void InitDecodedCert(DecodedCert* cert, byte* source, word32 inSz, void* heap)
cert->subjectOULen = 0;
cert->subjectEmail = 0;
cert->subjectEmailLen = 0;
cert->beforeDate = 0;
cert->beforeDateLen = 0;
cert->afterDate = 0;
cert->afterDateLen = 0;
#endif /* CYASSL_CERT_GEN */
cert->beforeDate = NULL;
cert->beforeDateLen = 0;
cert->afterDate = NULL;
cert->afterDateLen = 0;
#ifdef OPENSSL_EXTRA
XMEMSET(&cert->issuerName, 0, sizeof(DecodedName));
XMEMSET(&cert->subjectName, 0, sizeof(DecodedName));
#endif /* OPENSSL_EXTRA */
#ifdef CYASSL_SEP
cert->deviceTypeSz = 0;
cert->deviceType = NULL;
@ -1333,12 +1338,18 @@ void FreeDecodedCert(DecodedCert* cert)
XFREE(cert->hwType, cert->heap, 0);
XFREE(cert->hwSerialNum, cert->heap, 0);
#endif /* CYASSL_SEP */
#ifdef OPENSSL_EXTRA
if (cert->issuerName.fullName != NULL)
XFREE(cert->issuerName.fullName, NULL, DYNAMIC_TYPE_X509);
if (cert->subjectName.fullName != NULL)
XFREE(cert->subjectName.fullName, NULL, DYNAMIC_TYPE_X509);
#endif /* OPENSSL_EXTRA */
}
static int GetCertHeader(DecodedCert* cert)
{
int ret = 0, version, len;
int ret = 0, len;
byte serialTmp[EXTERNAL_SERIAL_SIZE];
mp_int mpi;
@ -1351,7 +1362,7 @@ static int GetCertHeader(DecodedCert* cert)
return ASN_PARSE_E;
cert->sigIndex = len + cert->srcIdx;
if (GetExplicitVersion(cert->source, &cert->srcIdx, &version) < 0)
if (GetExplicitVersion(cert->source, &cert->srcIdx, &cert->version) < 0)
return ASN_PARSE_E;
if (GetInt(&mpi, cert->source, &cert->srcIdx, cert->maxIdx) < 0)
@ -1537,6 +1548,10 @@ static int GetName(DecodedCert* cert, int nameType)
int dummy;
char* full = (nameType == ISSUER) ? cert->issuer : cert->subject;
word32 idx;
#ifdef OPENSSL_EXTRA
DecodedName* dName =
(nameType == ISSUER) ? &cert->issuerName : &cert->subjectName;
#endif /* OPENSSL_EXTRA */
CYASSL_MSG("Getting Cert Name");
@ -1621,6 +1636,10 @@ static int GetName(DecodedCert* cert, int nameType)
idx += 4;
copy = TRUE;
}
#ifdef OPENSSL_EXTRA
dName->cnIdx = cert->srcIdx;
dName->cnLen = strLen;
#endif /* OPENSSL_EXTRA */
}
else if (id == ASN_SUR_NAME) {
if (!tooBig) {
@ -1628,12 +1647,16 @@ static int GetName(DecodedCert* cert, int nameType)
idx += 4;
copy = TRUE;
}
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectSN = (char*)&cert->source[cert->srcIdx];
cert->subjectSNLen = strLen;
}
#endif /* CYASSL_CERT_GEN */
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectSN = (char*)&cert->source[cert->srcIdx];
cert->subjectSNLen = strLen;
}
#endif /* CYASSL_CERT_GEN */
#ifdef OPENSSL_EXTRA
dName->snIdx = cert->srcIdx;
dName->snLen = strLen;
#endif /* OPENSSL_EXTRA */
}
else if (id == ASN_COUNTRY_NAME) {
if (!tooBig) {
@ -1641,12 +1664,16 @@ static int GetName(DecodedCert* cert, int nameType)
idx += 3;
copy = TRUE;
}
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectC = (char*)&cert->source[cert->srcIdx];
cert->subjectCLen = strLen;
}
#endif /* CYASSL_CERT_GEN */
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectC = (char*)&cert->source[cert->srcIdx];
cert->subjectCLen = strLen;
}
#endif /* CYASSL_CERT_GEN */
#ifdef OPENSSL_EXTRA
dName->cIdx = cert->srcIdx;
dName->cLen = strLen;
#endif /* OPENSSL_EXTRA */
}
else if (id == ASN_LOCALITY_NAME) {
if (!tooBig) {
@ -1654,12 +1681,16 @@ static int GetName(DecodedCert* cert, int nameType)
idx += 3;
copy = TRUE;
}
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectL = (char*)&cert->source[cert->srcIdx];
cert->subjectLLen = strLen;
}
#endif /* CYASSL_CERT_GEN */
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectL = (char*)&cert->source[cert->srcIdx];
cert->subjectLLen = strLen;
}
#endif /* CYASSL_CERT_GEN */
#ifdef OPENSSL_EXTRA
dName->lIdx = cert->srcIdx;
dName->lLen = strLen;
#endif /* OPENSSL_EXTRA */
}
else if (id == ASN_STATE_NAME) {
if (!tooBig) {
@ -1667,12 +1698,16 @@ static int GetName(DecodedCert* cert, int nameType)
idx += 4;
copy = TRUE;
}
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectST = (char*)&cert->source[cert->srcIdx];
cert->subjectSTLen = strLen;
}
#endif /* CYASSL_CERT_GEN */
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectST = (char*)&cert->source[cert->srcIdx];
cert->subjectSTLen = strLen;
}
#endif /* CYASSL_CERT_GEN */
#ifdef OPENSSL_EXTRA
dName->stIdx = cert->srcIdx;
dName->stLen = strLen;
#endif /* OPENSSL_EXTRA */
}
else if (id == ASN_ORG_NAME) {
if (!tooBig) {
@ -1680,12 +1715,16 @@ static int GetName(DecodedCert* cert, int nameType)
idx += 3;
copy = TRUE;
}
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectO = (char*)&cert->source[cert->srcIdx];
cert->subjectOLen = strLen;
}
#endif /* CYASSL_CERT_GEN */
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectO = (char*)&cert->source[cert->srcIdx];
cert->subjectOLen = strLen;
}
#endif /* CYASSL_CERT_GEN */
#ifdef OPENSSL_EXTRA
dName->oIdx = cert->srcIdx;
dName->oLen = strLen;
#endif /* OPENSSL_EXTRA */
}
else if (id == ASN_ORGUNIT_NAME) {
if (!tooBig) {
@ -1693,12 +1732,16 @@ static int GetName(DecodedCert* cert, int nameType)
idx += 4;
copy = TRUE;
}
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectOU = (char*)&cert->source[cert->srcIdx];
cert->subjectOULen = strLen;
}
#endif /* CYASSL_CERT_GEN */
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectOU = (char*)&cert->source[cert->srcIdx];
cert->subjectOULen = strLen;
}
#endif /* CYASSL_CERT_GEN */
#ifdef OPENSSL_EXTRA
dName->ouIdx = cert->srcIdx;
dName->ouLen = strLen;
#endif /* OPENSSL_EXTRA */
}
else if (id == ASN_SERIAL_NUMBER) {
if (!tooBig) {
@ -1706,6 +1749,10 @@ static int GetName(DecodedCert* cert, int nameType)
idx += 14;
copy = TRUE;
}
#ifdef OPENSSL_EXTRA
dName->snIdx = cert->srcIdx;
dName->snLen = strLen;
#endif /* OPENSSL_EXTRA */
}
if (copy && !tooBig) {
@ -1747,12 +1794,16 @@ static int GetName(DecodedCert* cert, int nameType)
idx += 14;
}
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
cert->subjectEmailLen = adv;
}
#endif /* CYASSL_CERT_GEN */
#ifdef CYASSL_CERT_GEN
if (nameType == SUBJECT) {
cert->subjectEmail = (char*)&cert->source[cert->srcIdx];
cert->subjectEmailLen = adv;
}
#endif /* CYASSL_CERT_GEN */
#ifdef OPENSSL_EXTRA
dName->emailIdx = cert->srcIdx;
dName->emailLen = adv;
#endif /* OPENSSL_EXTRA */
if (!tooBig) {
XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
@ -1772,6 +1823,10 @@ static int GetName(DecodedCert* cert, int nameType)
XMEMCPY(&full[idx], &cert->source[cert->srcIdx], adv);
idx += adv;
}
#ifdef OPENSSL_EXTRA
dName->uidIdx = cert->srcIdx;
dName->uidLen = adv;
#endif /* OPENSSL_EXTRA */
}
cert->srcIdx += adv;
@ -1779,6 +1834,131 @@ static int GetName(DecodedCert* cert, int nameType)
}
full[idx++] = 0;
#ifdef OPENSSL_EXTRA
{
int totalLen = 0;
if (dName->cnLen != 0)
totalLen += dName->cnLen + 4;
if (dName->snLen != 0)
totalLen += dName->snLen + 4;
if (dName->cLen != 0)
totalLen += dName->cLen + 3;
if (dName->lLen != 0)
totalLen += dName->lLen + 3;
if (dName->stLen != 0)
totalLen += dName->stLen + 4;
if (dName->oLen != 0)
totalLen += dName->oLen + 3;
if (dName->ouLen != 0)
totalLen += dName->ouLen + 4;
if (dName->emailLen != 0)
totalLen += dName->emailLen + 14;
if (dName->uidLen != 0)
totalLen += dName->uidLen + 5;
if (dName->serialLen != 0)
totalLen += dName->serialLen + 14;
dName->fullName = (char*)XMALLOC(totalLen + 1, NULL, DYNAMIC_TYPE_X509);
if (dName->fullName != NULL) {
idx = 0;
if (dName->cnLen != 0) {
dName->entryCount++;
XMEMCPY(&dName->fullName[idx], "/CN=", 4);
idx += 4;
XMEMCPY(&dName->fullName[idx],
&cert->source[dName->cnIdx], dName->cnLen);
dName->cnIdx = idx;
idx += dName->cnLen;
}
if (dName->snLen != 0) {
dName->entryCount++;
XMEMCPY(&dName->fullName[idx], "/SN=", 4);
idx += 4;
XMEMCPY(&dName->fullName[idx],
&cert->source[dName->snIdx], dName->snLen);
dName->snIdx = idx;
idx += dName->snLen;
}
if (dName->cLen != 0) {
dName->entryCount++;
XMEMCPY(&dName->fullName[idx], "/C=", 3);
idx += 3;
XMEMCPY(&dName->fullName[idx],
&cert->source[dName->cIdx], dName->cLen);
dName->cIdx = idx;
idx += dName->cLen;
}
if (dName->lLen != 0) {
dName->entryCount++;
XMEMCPY(&dName->fullName[idx], "/L=", 3);
idx += 3;
XMEMCPY(&dName->fullName[idx],
&cert->source[dName->lIdx], dName->lLen);
dName->lIdx = idx;
idx += dName->lLen;
}
if (dName->stLen != 0) {
dName->entryCount++;
XMEMCPY(&dName->fullName[idx], "/ST=", 4);
idx += 4;
XMEMCPY(&dName->fullName[idx],
&cert->source[dName->stIdx], dName->stLen);
dName->stIdx = idx;
idx += dName->stLen;
}
if (dName->oLen != 0) {
dName->entryCount++;
XMEMCPY(&dName->fullName[idx], "/O=", 3);
idx += 3;
XMEMCPY(&dName->fullName[idx],
&cert->source[dName->oIdx], dName->oLen);
dName->oIdx = idx;
idx += dName->oLen;
}
if (dName->ouLen != 0) {
dName->entryCount++;
XMEMCPY(&dName->fullName[idx], "/OU=", 4);
idx += 4;
XMEMCPY(&dName->fullName[idx],
&cert->source[dName->ouIdx], dName->ouLen);
dName->ouIdx = idx;
idx += dName->ouLen;
}
if (dName->emailLen != 0) {
dName->entryCount++;
XMEMCPY(&dName->fullName[idx], "/emailAddress=", 14);
idx += 14;
XMEMCPY(&dName->fullName[idx],
&cert->source[dName->emailIdx], dName->emailLen);
dName->emailIdx = idx;
idx += dName->emailLen;
}
if (dName->uidLen != 0) {
dName->entryCount++;
XMEMCPY(&dName->fullName[idx], "/UID=", 5);
idx += 5;
XMEMCPY(&dName->fullName[idx],
&cert->source[dName->uidIdx], dName->uidLen);
dName->uidIdx = idx;
idx += dName->uidLen;
}
if (dName->serialLen != 0) {
dName->entryCount++;
XMEMCPY(&dName->fullName[idx], "/serialNumber=", 14);
idx += 14;
XMEMCPY(&dName->fullName[idx],
&cert->source[dName->serialIdx], dName->serialLen);
dName->serialIdx = idx;
idx += dName->serialLen;
}
dName->fullName[idx] = '\0';
dName->fullNameLen = totalLen;
}
}
#endif /* OPENSSL_EXTRA */
return 0;
}
@ -1878,15 +2058,13 @@ static int GetDate(DecodedCert* cert, int dateType)
int length;
byte date[MAX_DATE_SIZE];
byte b;
#ifdef CYASSL_CERT_GEN
word32 startIdx = 0;
if (dateType == BEFORE)
cert->beforeDate = &cert->source[cert->srcIdx];
else
cert->afterDate = &cert->source[cert->srcIdx];
startIdx = cert->srcIdx;
#endif
b = cert->source[cert->srcIdx++];
if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
@ -1901,12 +2079,10 @@ static int GetDate(DecodedCert* cert, int dateType)
XMEMCPY(date, &cert->source[cert->srcIdx], length);
cert->srcIdx += length;
#ifdef CYASSL_CERT_GEN
if (dateType == BEFORE)
cert->beforeDateLen = cert->srcIdx - startIdx;
else
cert->afterDateLen = cert->srcIdx - startIdx;
#endif
if (!XVALIDATE_DATE(date, b, dateType)) {
if (dateType == BEFORE)

View File

@ -223,7 +223,36 @@ struct DNS_entry {
char* name; /* actual DNS name */
};
struct DecodedName {
char* fullName;
int fullNameLen;
int entryCount;
int cnIdx;
int cnLen;
int snIdx;
int snLen;
int cIdx;
int cLen;
int lIdx;
int lLen;
int stIdx;
int stLen;
int oIdx;
int oLen;
int ouIdx;
int ouLen;
int emailIdx;
int emailLen;
int uidIdx;
int uidLen;
int serialIdx;
int serialLen;
};
typedef struct DecodedCert DecodedCert;
typedef struct DecodedName DecodedName;
typedef struct Signer Signer;
@ -236,6 +265,7 @@ struct DecodedCert {
word32 sigLength; /* length of signature */
word32 signatureOID; /* sum of algorithm object id */
word32 keyOID; /* sum of key algo object id */
int version; /* cert version, 1 or 3 */
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 */
@ -267,7 +297,11 @@ struct DecodedCert {
byte extAuthKeyId[SHA_SIZE]; /* Authority Key ID */
byte extAuthKeyIdSet; /* Set when the AKID was read from cert */
byte isCA; /* CA basic constraint true */
#ifdef CYASSL_CERT_GEN
byte* beforeDate;
int beforeDateLen;
byte* afterDate;
int afterDateLen;
#if defined(CYASSL_CERT_GEN)
/* easy access to subject info for other sign */
char* subjectSN;
int subjectSNLen;
@ -283,11 +317,11 @@ struct DecodedCert {
int subjectOULen;
char* subjectEmail;
int subjectEmailLen;
byte* beforeDate;
int beforeDateLen;
byte* afterDate;
int afterDateLen;
#endif /* CYASSL_CERT_GEN */
#ifdef OPENSSL_EXTRA
DecodedName issuerName;
DecodedName subjectName;
#endif /* OPENSSL_EXTRA */
#ifdef CYASSL_SEP
int deviceTypeSz;
byte* deviceType;
@ -298,6 +332,7 @@ struct DecodedCert {
#endif /* CYASSL_SEP */
};
#ifdef SHA_DIGEST_SIZE
#define SIGNER_DIGEST_SIZE SHA_DIGEST_SIZE
#else

View File

@ -1621,9 +1621,18 @@ typedef struct Arrays {
#define ASN_NAME_MAX 256
#endif
#ifndef MAX_DATE_SZ
#define MAX_DATE_SZ 32
#endif
struct CYASSL_X509_NAME {
char name[ASN_NAME_MAX];
char *name;
char staticName[ASN_NAME_MAX];
int dynamicName;
int sz;
#ifdef OPENSSL_EXTRA
DecodedName fullName;
#endif /* OPENSSL_EXTRA */
};
#ifndef EXTERNAL_SERIAL_SIZE
@ -1635,6 +1644,7 @@ struct CYASSL_X509_NAME {
#endif
struct CYASSL_X509 {
int version;
CYASSL_X509_NAME issuer;
CYASSL_X509_NAME subject;
int serialSz;
@ -1648,6 +1658,11 @@ struct CYASSL_X509 {
int hwSerialNumSz;
byte hwSerialNum[EXTERNAL_SERIAL_SIZE];
#endif
int notBeforeSz;
byte notBefore[MAX_DATE_SZ];
int notAfterSz;
byte notAfter[MAX_DATE_SZ];
buffer pubKey;
buffer derCert; /* may need */
DNS_entry* altNames; /* alt names list */
DNS_entry* altNamesNext; /* hint for retrieval */
@ -2025,6 +2040,8 @@ CYASSL_LOCAL int GrowInputBuffer(CYASSL* ssl, int size, int usedLength);
CYASSL_LOCAL word32 LowResTimer(void);
CYASSL_LOCAL void InitX509Name(CYASSL_X509_NAME*, int);
CYASSL_LOCAL void FreeX509Name(CYASSL_X509_NAME* name);
CYASSL_LOCAL void InitX509(CYASSL_X509*, int);
CYASSL_LOCAL void FreeX509(CYASSL_X509*);
#ifndef NO_CERTS

View File

@ -95,6 +95,10 @@ typedef struct CYASSL_dynlock_value CYASSL_dynlock_value;
typedef struct CYASSL_EVP_PKEY {
int type; /* openssh dereference */
int save_type; /* openssh dereference */
int pkey_sz;
union {
char* ptr;
} pkey;
} CYASSL_EVP_PKEY;
typedef struct CYASSL_MD4_CTX {
@ -108,7 +112,8 @@ typedef struct CYASSL_COMP_METHOD {
typedef struct CYASSL_X509_STORE {
int cache; /* stunnel dereference */
int cache; /* stunnel dereference */
CYASSL_CERT_MANAGER* cm;
} CYASSL_X509_STORE;
typedef struct CYASSL_ALERT {
@ -135,6 +140,7 @@ typedef struct CYASSL_X509_OBJECT {
typedef struct CYASSL_X509_STORE_CTX {
CYASSL_X509_STORE* store; /* Store full of a CA cert chain */
CYASSL_X509* current_cert; /* stunnel dereference */
char* domain; /* subject CN domain name */
void* ex_data; /* external data, for fortress build */
@ -407,6 +413,10 @@ CYASSL_API int CyaSSL_X509_STORE_CTX_get_error_depth(CYASSL_X509_STORE_CTX*);
CYASSL_API char* CyaSSL_X509_NAME_oneline(CYASSL_X509_NAME*, char*, int);
CYASSL_API CYASSL_X509_NAME* CyaSSL_X509_get_issuer_name(CYASSL_X509*);
CYASSL_API CYASSL_X509_NAME* CyaSSL_X509_get_subject_name(CYASSL_X509*);
CYASSL_API int CyaSSL_X509_NAME_entry_count(CYASSL_X509_NAME*);
CYASSL_API int CyaSSL_X509_NAME_get_text_by_NID(
CYASSL_X509_NAME*, int, char*, int);
CYASSL_API int CyaSSL_X509_verify_cert(CYASSL_X509_STORE_CTX*);
CYASSL_API const char* CyaSSL_X509_verify_cert_error_string(long);
CYASSL_API int CyaSSL_X509_LOOKUP_add_dir(CYASSL_X509_LOOKUP*,const char*,long);
@ -418,10 +428,16 @@ CYASSL_API CYASSL_X509_LOOKUP_METHOD* CyaSSL_X509_LOOKUP_file(void);
CYASSL_API CYASSL_X509_LOOKUP* CyaSSL_X509_STORE_add_lookup(CYASSL_X509_STORE*,
CYASSL_X509_LOOKUP_METHOD*);
CYASSL_API CYASSL_X509_STORE* CyaSSL_X509_STORE_new(void);
CYASSL_API void CyaSSL_X509_STORE_free(CYASSL_X509_STORE*);
CYASSL_API int CyaSSL_X509_STORE_add_cert(
CYASSL_X509_STORE*, CYASSL_X509*);
CYASSL_API int CyaSSL_X509_STORE_set_default_paths(CYASSL_X509_STORE*);
CYASSL_API int CyaSSL_X509_STORE_get_by_subject(CYASSL_X509_STORE_CTX*,
int, CYASSL_X509_NAME*, CYASSL_X509_OBJECT*);
CYASSL_API CYASSL_X509_STORE_CTX* CyaSSL_X509_STORE_CTX_new(void);
CYASSL_API int CyaSSL_X509_STORE_CTX_init(CYASSL_X509_STORE_CTX*,
CYASSL_X509_STORE*, CYASSL_X509*, STACK_OF(CYASSL_X509)*);
CYASSL_API void CyaSSL_X509_STORE_CTX_free(CYASSL_X509_STORE_CTX*);
CYASSL_API void CyaSSL_X509_STORE_CTX_cleanup(CYASSL_X509_STORE_CTX*);
CYASSL_API CYASSL_ASN1_TIME* CyaSSL_X509_CRL_get_lastUpdate(CYASSL_X509_CRL*);
@ -778,13 +794,21 @@ CYASSL_API const unsigned char* CyaSSL_get_sessionID(const CYASSL_SESSION* s);
CYASSL_API int CyaSSL_X509_get_serial_number(CYASSL_X509*,unsigned char*,int*);
CYASSL_API char* CyaSSL_X509_get_subjectCN(CYASSL_X509*);
CYASSL_API const unsigned char* CyaSSL_X509_get_der(CYASSL_X509*, int*);
CYASSL_API const unsigned char* CyaSSL_X509_notBefore(CYASSL_X509*);
CYASSL_API const unsigned char* CyaSSL_X509_notAfter(CYASSL_X509*);
CYASSL_API int CyaSSL_X509_version(CYASSL_X509*);
CYASSL_API
CYASSL_API int CyaSSL_cmp_peer_cert_to_file(CYASSL*, const char*);
CYASSL_API char* CyaSSL_X509_get_next_altname(CYASSL_X509*);
CYASSL_API
CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format);
CYASSL_API CYASSL_X509*
CyaSSL_X509_d2i(CYASSL_X509** x509, const unsigned char* in, int len);
CYASSL_API CYASSL_X509*
CyaSSL_X509_d2i_fp(CYASSL_X509** x509, FILE* file);
CYASSL_API CYASSL_X509*
CyaSSL_X509_load_certificate_file(const char* fname, int format);
#ifdef CYASSL_SEP
CYASSL_API unsigned char*

View File

@ -1231,9 +1231,41 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK,
#ifndef NO_CERTS
void InitX509Name(CYASSL_X509_NAME* name, int dynamicFlag)
{
(void)dynamicFlag;
if (name != NULL) {
name->name = name->staticName;
name->dynamicName = 0;
#ifdef OPENSSL_EXTRA
XMEMSET(&name->fullName, 0, sizeof(DecodedName));
#endif /* OPENSSL_EXTRA */
}
}
void FreeX509Name(CYASSL_X509_NAME* name)
{
if (name != NULL) {
if (name->dynamicName)
XFREE(name->name, NULL, DYNAMIC_TYPE_SUBJECT_CN);
#ifdef OPENSSL_EXTRA
if (name->fullName.fullName != NULL)
XFREE(name->fullName.fullName, NULL, DYNAMIC_TYPE_X509);
#endif /* OPENSSL_EXTRA */
}
}
/* Initialize CyaSSL X509 type */
void InitX509(CYASSL_X509* x509, int dynamicFlag)
{
InitX509Name(&x509->issuer, 0);
InitX509Name(&x509->subject, 0);
x509->version = 0;
x509->pubKey.buffer = NULL;
x509->derCert.buffer = NULL;
x509->altNames = NULL;
x509->altNamesNext = NULL;
@ -1247,7 +1279,11 @@ void FreeX509(CYASSL_X509* x509)
if (x509 == NULL)
return;
XFREE(x509->derCert.buffer, NULL, DYNAMIC_TYPE_CERT);
FreeX509Name(&x509->issuer);
FreeX509Name(&x509->subject);
if (x509->pubKey.buffer)
XFREE(x509->pubKey.buffer, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
XFREE(x509->derCert.buffer, NULL, DYNAMIC_TYPE_SUBJECT_CN);
if (x509->altNames)
FreeAltNames(x509->altNames, NULL);
if (x509->dynamicMemory)
@ -2998,13 +3034,37 @@ int CopyDecodedToX509(CYASSL_X509* x509, DecodedCert* dCert)
if (x509 == NULL || dCert == NULL)
return BAD_FUNC_ARG;
x509->version = dCert->version + 1;
XSTRNCPY(x509->issuer.name, dCert->issuer, ASN_NAME_MAX);
x509->issuer.name[ASN_NAME_MAX - 1] = '\0';
x509->issuer.sz = (int)XSTRLEN(x509->issuer.name) + 1;
#ifdef OPENSSL_EXTRA
if (dCert->issuerName.fullName != NULL) {
XMEMCPY(&x509->issuer.fullName,
&dCert->issuerName, sizeof(DecodedName));
x509->issuer.fullName.fullName = (char*)XMALLOC(
dCert->issuerName.fullNameLen, NULL, DYNAMIC_TYPE_X509);
if (x509->issuer.fullName.fullName != NULL)
XMEMCPY(x509->issuer.fullName.fullName,
dCert->issuerName.fullName, dCert->issuerName.fullNameLen);
}
#endif /* OPENSSL_EXTRA */
XSTRNCPY(x509->subject.name, dCert->subject, ASN_NAME_MAX);
x509->subject.name[ASN_NAME_MAX - 1] = '\0';
x509->subject.sz = (int)XSTRLEN(x509->subject.name) + 1;
#ifdef OPENSSL_EXTRA
if (dCert->subjectName.fullName != NULL) {
XMEMCPY(&x509->subject.fullName,
&dCert->subjectName, sizeof(DecodedName));
x509->subject.fullName.fullName = (char*)XMALLOC(
dCert->subjectName.fullNameLen, NULL, DYNAMIC_TYPE_X509);
if (x509->subject.fullName.fullName != NULL)
XMEMCPY(x509->subject.fullName.fullName,
dCert->subjectName.fullName, dCert->subjectName.fullNameLen);
}
#endif /* OPENSSL_EXTRA */
XMEMCPY(x509->serial, dCert->serial, EXTERNAL_SERIAL_SIZE);
x509->serialSz = dCert->serialSz;
@ -3040,6 +3100,33 @@ int CopyDecodedToX509(CYASSL_X509* x509, DecodedCert* dCert)
x509->hwSerialNumSz = 0;
}
#endif /* CYASSL_SEP */
{
int minSz = min(dCert->beforeDateLen, MAX_DATE_SZ);
if (minSz != 0) {
x509->notBeforeSz = minSz;
XMEMCPY(x509->notBefore, dCert->beforeDate, minSz);
}
else
x509->notBeforeSz = 0;
minSz = min(dCert->afterDateLen, MAX_DATE_SZ);
if (minSz != 0) {
x509->notAfterSz = minSz;
XMEMCPY(x509->notAfter, dCert->afterDate, minSz);
}
else
x509->notAfterSz = 0;
}
if (dCert->publicKey != NULL && dCert->pubKeySize != 0) {
x509->pubKey.buffer = (byte*)XMALLOC(
dCert->pubKeySize, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
if (x509->pubKey.buffer != NULL) {
x509->pubKey.length = dCert->pubKeySize;
XMEMCPY(x509->pubKey.buffer, dCert->publicKey, dCert->pubKeySize);
}
else
ret = MEMORY_E;
}
/* store cert for potential retrieval */
x509->derCert.buffer = (byte*)XMALLOC(dCert->maxIdx, NULL,

300
src/ssl.c
View File

@ -5613,7 +5613,8 @@ int CyaSSL_set_compression(CYASSL* ssl)
int CyaSSL_X509_STORE_CTX_get_error(CYASSL_X509_STORE_CTX* ctx)
{
(void)ctx;
if (ctx != NULL)
return ctx->error;
return 0;
}
@ -7066,6 +7067,76 @@ int CyaSSL_set_compression(CYASSL* ssl)
}
int CyaSSL_X509_NAME_entry_count(CYASSL_X509_NAME* name)
{
int count = 0;
CYASSL_ENTER("CyaSSL_X509_NAME_entry_count");
if (name != NULL)
count = name->fullName.entryCount;
CYASSL_LEAVE("CyaSSL_X509_NAME_entry_count", count);
return count;
}
int CyaSSL_X509_NAME_get_text_by_NID(CYASSL_X509_NAME* name,
int nid, char* buf, int len)
{
char *text = NULL;
int textSz = 0;
CYASSL_ENTER("CyaSSL_X509_NAME_get_text_by_NID");
switch (nid) {
case ASN_COMMON_NAME:
text = name->fullName.fullName + name->fullName.cnIdx;
textSz = name->fullName.cnLen;
break;
case ASN_SUR_NAME:
text = name->fullName.fullName + name->fullName.snIdx;
textSz = name->fullName.snLen;
break;
case ASN_SERIAL_NUMBER:
text = name->fullName.fullName + name->fullName.serialIdx;
textSz = name->fullName.serialLen;
break;
case ASN_COUNTRY_NAME:
text = name->fullName.fullName + name->fullName.cIdx;
textSz = name->fullName.cLen;
break;
case ASN_LOCALITY_NAME:
text = name->fullName.fullName + name->fullName.lIdx;
textSz = name->fullName.lLen;
break;
case ASN_STATE_NAME:
text = name->fullName.fullName + name->fullName.stIdx;
textSz = name->fullName.stLen;
break;
case ASN_ORG_NAME:
text = name->fullName.fullName + name->fullName.oIdx;
textSz = name->fullName.oLen;
break;
case ASN_ORGUNIT_NAME:
text = name->fullName.fullName + name->fullName.ouIdx;
textSz = name->fullName.ouLen;
break;
default:
break;
}
if (buf != NULL) {
textSz = min(textSz, len);
XMEMCPY(buf, text, textSz);
buf[textSz] = '\0';
}
CYASSL_LEAVE("CyaSSL_X509_NAME_get_text_by_NID", textSz);
return textSz;
}
/* write X509 serial number in unsigned binary to buffer
buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
return SSL_SUCCESS on success */
@ -7093,6 +7164,40 @@ int CyaSSL_set_compression(CYASSL* ssl)
return x509->derCert.buffer;
}
int CyaSSL_X509_version(CYASSL_X509* x509)
{
CYASSL_ENTER("CyaSSL_X509_version");
if (x509 == NULL)
return 0;
return x509->version;
}
const byte* CyaSSL_X509_notBefore(CYASSL_X509* x509)
{
CYASSL_ENTER("CyaSSL_X509_notBefore");
if (x509 == NULL)
return NULL;
return x509->notBefore;
}
const byte* CyaSSL_X509_notAfter(CYASSL_X509* x509)
{
CYASSL_ENTER("CyaSSL_X509_notAfter");
if (x509 == NULL)
return NULL;
return x509->notAfter;
}
#ifdef CYASSL_SEP
/* copy oid into in buffer, at most *inOutSz bytes, if buffer is null will
@ -7169,6 +7274,66 @@ byte* CyaSSL_X509_get_hw_serial_number(CYASSL_X509* x509,byte* in,int* inOutSz)
#endif /* CYASSL_SEP */
CYASSL_X509* CyaSSL_X509_d2i(CYASSL_X509** x509, const byte* in, int len)
{
CYASSL_X509 *newX509 = NULL;
CYASSL_ENTER("CyaSSL_X509_d2i");
if (in != NULL && len != 0) {
DecodedCert cert;
InitDecodedCert(&cert, (byte*)in, len, NULL);
if (ParseCertRelative(&cert, CERT_TYPE, 0, NULL) == 0) {
newX509 = (CYASSL_X509*)XMALLOC(sizeof(CYASSL_X509),
NULL, DYNAMIC_TYPE_X509);
if (newX509 != NULL) {
InitX509(newX509, 1);
if (CopyDecodedToX509(newX509, &cert) != 0) {
XFREE(newX509, NULL, DYNAMIC_TYPE_X509);
newX509 = NULL;
}
}
}
FreeDecodedCert(&cert);
}
if (x509 != NULL)
*x509 = newX509;
return newX509;
}
CYASSL_X509* CyaSSL_X509_d2i_fp(CYASSL_X509** x509, XFILE file)
{
CYASSL_X509* newX509 = NULL;
CYASSL_ENTER("CyaSSL_X509_d2i_fp");
if (file != XBADFILE) {
byte* fileBuffer = NULL;
long sz = 0;
XFSEEK(file, 0, XSEEK_END);
sz = XFTELL(file);
XREWIND(file);
fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
if (fileBuffer != NULL) {
if ((int)XFREAD(fileBuffer, sz, 1, file) > 0) {
newX509 = CyaSSL_X509_d2i(NULL, fileBuffer, (int)sz);
}
XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
}
}
if (x509 != NULL)
*x509 = newX509;
return newX509;
}
CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format)
{
byte staticBuffer[FILE_BUFFER_SIZE];
@ -7965,9 +8130,61 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format)
}
int CyaSSL_X509_STORE_add_cert(CYASSL_X509_STORE* store, CYASSL_X509* x509)
{
int result = SSL_FATAL_ERROR;
CYASSL_ENTER("CyaSSL_X509_STORE_add_cert");
if (store != NULL && store->cm != NULL && x509 != NULL) {
buffer derCert;
derCert.buffer = (byte*)XMALLOC(x509->derCert.length,
NULL, DYNAMIC_TYPE_CERT);
if (derCert.buffer != NULL) {
derCert.length = x509->derCert.length;
// AddCA() frees the buffer.
XMEMCPY(derCert.buffer,
x509->derCert.buffer, x509->derCert.length);
result = AddCA(store->cm, derCert, CYASSL_USER_CA, 1);
if (result != SSL_SUCCESS) result = SSL_FATAL_ERROR;
}
}
CYASSL_LEAVE("CyaSSL_X509_STORE_add_cert", result);
return result;
}
CYASSL_X509_STORE* CyaSSL_X509_STORE_new(void)
{
return 0;
CYASSL_X509_STORE* store = NULL;
store = (CYASSL_X509_STORE*)XMALLOC(sizeof(CYASSL_X509_STORE), NULL, 0);
if (store != NULL) {
store->cm = CyaSSL_CertManagerNew();
if (store->cm == NULL) {
XFREE(store, NULL, 0);
store = NULL;
}
}
return store;
}
void CyaSSL_X509_STORE_free(CYASSL_X509_STORE* store)
{
if (store != NULL) {
if (store->cm != NULL)
CyaSSL_CertManagerFree(store->cm);
XFREE(store, NULL, 0);
}
}
int CyaSSL_X509_STORE_set_default_paths(CYASSL_X509_STORE* store)
{
(void)store;
return SSL_SUCCESS;
}
@ -7982,14 +8199,46 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format)
}
CYASSL_X509_STORE_CTX* CyaSSL_X509_STORE_CTX_new(void)
{
CYASSL_X509_STORE_CTX* ctx = (CYASSL_X509_STORE_CTX*)XMALLOC(
sizeof(CYASSL_X509_STORE_CTX), NULL, 0);
if (ctx != NULL)
CyaSSL_X509_STORE_CTX_init(ctx, NULL, NULL, NULL);
return ctx;
}
int CyaSSL_X509_STORE_CTX_init(CYASSL_X509_STORE_CTX* ctx,
CYASSL_X509_STORE* store, CYASSL_X509* x509, STACK_OF(CYASSL_X509)* sk)
{
(void)ctx;
(void)store;
(void)x509;
(void)sk;
return 0;
if (ctx != NULL) {
ctx->store = store;
ctx->current_cert = x509;
ctx->domain = NULL;
ctx->ex_data = NULL;
ctx->userCtx = NULL;
ctx->error = 0;
ctx->error_depth = 0;
ctx->discardSessionCerts = 0;
return SSL_SUCCESS;
}
return SSL_FATAL_ERROR;
}
void CyaSSL_X509_STORE_CTX_free(CYASSL_X509_STORE_CTX* ctx)
{
if (ctx != NULL) {
if (ctx->store != NULL)
CyaSSL_X509_STORE_free(ctx->store);
if (ctx->current_cert != NULL)
CyaSSL_FreeX509(ctx->current_cert);
XFREE(ctx, NULL, 0);
}
}
@ -7999,6 +8248,18 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format)
}
int CyaSSL_X509_verify_cert(CYASSL_X509_STORE_CTX* ctx)
{
if (ctx != NULL && ctx->store != NULL && ctx->store->cm != NULL
&& ctx->current_cert != NULL) {
return CyaSSL_CertManagerVerifyBuffer(ctx->store->cm,
ctx->current_cert->derCert.buffer,
ctx->current_cert->derCert.length,
SSL_FILETYPE_ASN1);
}
return SSL_FATAL_ERROR;
}
CYASSL_ASN1_TIME* CyaSSL_X509_CRL_get_lastUpdate(CYASSL_X509_CRL* crl)
{
@ -8017,8 +8278,25 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format)
CYASSL_EVP_PKEY* CyaSSL_X509_get_pubkey(CYASSL_X509* x509)
{
(void)x509;
return 0;
CYASSL_EVP_PKEY* key = NULL;
if (x509 != NULL) {
key = (CYASSL_EVP_PKEY*)XMALLOC(
sizeof(CYASSL_EVP_PKEY), NULL, DYNAMIC_TYPE_PUBLIC_KEY);
if (key != NULL) {
key->type = 0;
key->save_type = 0;
key->pkey.ptr = (char*)XMALLOC(
x509->pubKey.length, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
if (key->pkey.ptr == NULL) {
XFREE(key, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
return NULL;
}
XMEMCPY(key->pkey.ptr,
x509->pubKey.buffer, x509->pubKey.length);
key->pkey_sz = x509->pubKey.length;
}
}
return key;
}
@ -8045,7 +8323,11 @@ CYASSL_X509* CyaSSL_X509_load_certificate_file(const char* fname, int format)
void CyaSSL_EVP_PKEY_free(CYASSL_EVP_PKEY* key)
{
(void)key;
if (key != NULL) {
if (key->pkey.ptr != NULL)
XFREE(key->pkey.ptr, NULL, 0);
XFREE(key, NULL, 0);
}
}