forked from wolfSSL/wolfssl
add verify from root, top->down, serial number extension for size
This commit is contained in:
@@ -42,6 +42,7 @@ enum {
|
|||||||
SUBJECT = 1,
|
SUBJECT = 1,
|
||||||
|
|
||||||
SERIAL_SIZE = 8,
|
SERIAL_SIZE = 8,
|
||||||
|
EXTERNAL_SERIAL_SIZE = 32,
|
||||||
|
|
||||||
BEFORE = 0,
|
BEFORE = 0,
|
||||||
AFTER = 1
|
AFTER = 1
|
||||||
@@ -188,7 +189,8 @@ typedef struct DecodedCert {
|
|||||||
byte* source; /* byte buffer holder cert, NOT owner */
|
byte* source; /* byte buffer holder cert, NOT owner */
|
||||||
word32 srcIdx; /* current offset into buffer */
|
word32 srcIdx; /* current offset into buffer */
|
||||||
void* heap; /* for user memory overrides */
|
void* heap; /* for user memory overrides */
|
||||||
byte serial[SERIAL_SIZE]; /* raw serial number */
|
byte serial[EXTERNAL_SERIAL_SIZE]; /* raw serial number */
|
||||||
|
int serialSz; /* raw serial bytes stored */
|
||||||
#ifdef CYASSL_CERT_GEN
|
#ifdef CYASSL_CERT_GEN
|
||||||
/* easy access to sujbect info for other sign */
|
/* easy access to sujbect info for other sign */
|
||||||
char* subjectSN;
|
char* subjectSN;
|
||||||
|
@@ -828,7 +828,8 @@ void InitDecodedCert(DecodedCert* cert, byte* source, void* heap)
|
|||||||
cert->source = source; /* don't own */
|
cert->source = source; /* don't own */
|
||||||
cert->srcIdx = 0;
|
cert->srcIdx = 0;
|
||||||
cert->heap = heap;
|
cert->heap = heap;
|
||||||
XMEMSET(cert->serial, 0, SERIAL_SIZE);
|
XMEMSET(cert->serial, 0, EXTERNAL_SERIAL_SIZE);
|
||||||
|
cert->serialSz = 0;
|
||||||
#ifdef CYASSL_CERT_GEN
|
#ifdef CYASSL_CERT_GEN
|
||||||
cert->subjectSN = 0;
|
cert->subjectSN = 0;
|
||||||
cert->subjectSNLen = 0;
|
cert->subjectSNLen = 0;
|
||||||
@@ -861,6 +862,7 @@ static int GetCertHeader(DecodedCert* cert, word32 inSz)
|
|||||||
{
|
{
|
||||||
int ret = 0, version, len;
|
int ret = 0, version, len;
|
||||||
word32 begin = cert->srcIdx;
|
word32 begin = cert->srcIdx;
|
||||||
|
byte serialTmp[EXTERNAL_SERIAL_SIZE];
|
||||||
mp_int mpi;
|
mp_int mpi;
|
||||||
|
|
||||||
if (GetSequence(cert->source, &cert->srcIdx, &len) < 0)
|
if (GetSequence(cert->source, &cert->srcIdx, &len) < 0)
|
||||||
@@ -880,11 +882,14 @@ static int GetCertHeader(DecodedCert* cert, word32 inSz)
|
|||||||
return ASN_PARSE_E;
|
return ASN_PARSE_E;
|
||||||
|
|
||||||
len = mp_unsigned_bin_size(&mpi);
|
len = mp_unsigned_bin_size(&mpi);
|
||||||
if (len > SERIAL_SIZE)
|
if (len < sizeof(serialTmp)) {
|
||||||
len = SERIAL_SIZE; /* use first 64 bits for unique id */
|
if (mp_to_unsigned_bin(&mpi, serialTmp) == MP_OKAY) {
|
||||||
if (mp_to_unsigned_bin(&mpi, cert->serial + (SERIAL_SIZE - len)) != MP_OKAY)
|
if (len > EXTERNAL_SERIAL_SIZE)
|
||||||
ret = MP_TO_E;
|
len = EXTERNAL_SERIAL_SIZE;
|
||||||
|
XMEMCPY(cert->serial, serialTmp, len);
|
||||||
|
cert->serialSz = len;
|
||||||
|
}
|
||||||
|
}
|
||||||
mp_clear(&mpi);
|
mp_clear(&mpi);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1632,8 +1637,10 @@ static int ConfirmSignature(DecodedCert* cert, const byte* key, word32 keySz,
|
|||||||
digestSz = SHA256_DIGEST_SIZE;
|
digestSz = SHA256_DIGEST_SIZE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else {
|
||||||
|
// TAO CYASSL_MSG("Verify Signautre has unsupported type");
|
||||||
return 0; /* ASN_SIG_HASH_E; */
|
return 0; /* ASN_SIG_HASH_E; */
|
||||||
|
}
|
||||||
|
|
||||||
if (keyOID == RSAk) {
|
if (keyOID == RSAk) {
|
||||||
RsaKey pubKey;
|
RsaKey pubKey;
|
||||||
@@ -1746,6 +1753,10 @@ int ParseCert(DecodedCert* cert, word32 inSz, int type, int verify,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* from SSL proper, for locking can't do find here anymore */
|
||||||
|
Signer* GetCA(Signer* signers, byte* hash);
|
||||||
|
|
||||||
|
|
||||||
int ParseCertRelative(DecodedCert* cert, word32 inSz, int type, int verify,
|
int ParseCertRelative(DecodedCert* cert, word32 inSz, int type, int verify,
|
||||||
Signer* signers)
|
Signer* signers)
|
||||||
{
|
{
|
||||||
@@ -1774,23 +1785,20 @@ int ParseCertRelative(DecodedCert* cert, word32 inSz, int type, int verify,
|
|||||||
return ASN_SIG_OID_E;
|
return ASN_SIG_OID_E;
|
||||||
|
|
||||||
if (verify && type != CA_TYPE) {
|
if (verify && type != CA_TYPE) {
|
||||||
while (signers) {
|
Signer* signer = GetCA(signers, cert->issuerHash);
|
||||||
if (XMEMCMP(cert->issuerHash, signers->hash, SHA_DIGEST_SIZE)
|
|
||||||
== 0) {
|
if (signer) {
|
||||||
/* other confirm */
|
/* try to confirm/verify signature */
|
||||||
if (!ConfirmSignature(cert, signers->publicKey,
|
if (!ConfirmSignature(cert, signers->publicKey,
|
||||||
signers->pubKeySize, signers->keyOID))
|
signers->pubKeySize, signers->keyOID))
|
||||||
return ASN_SIG_CONFIRM_E;
|
return ASN_SIG_CONFIRM_E;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
confirm = 1;
|
/* no signer */
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
signers = signers->next;
|
|
||||||
}
|
|
||||||
if (!confirm)
|
|
||||||
return ASN_SIG_CONFIRM_E;
|
return ASN_SIG_CONFIRM_E;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (badDate != 0)
|
if (badDate != 0)
|
||||||
return badDate;
|
return badDate;
|
||||||
|
|
||||||
@@ -2219,6 +2227,7 @@ void InitCert(Cert* cert)
|
|||||||
cert->bodySz = 0;
|
cert->bodySz = 0;
|
||||||
cert->keyType = RSA_KEY;
|
cert->keyType = RSA_KEY;
|
||||||
XMEMSET(cert->serial, 0, SERIAL_SIZE);
|
XMEMSET(cert->serial, 0, SERIAL_SIZE);
|
||||||
|
cert->serialSz = 0;
|
||||||
|
|
||||||
cert->issuer.country[0] = '\0';
|
cert->issuer.country[0] = '\0';
|
||||||
cert->issuer.state[0] = '\0';
|
cert->issuer.state[0] = '\0';
|
||||||
|
@@ -160,6 +160,7 @@ void client_test(void* args)
|
|||||||
|
|
||||||
ssl = SSL_new(ctx);
|
ssl = SSL_new(ctx);
|
||||||
SSL_set_fd(ssl, sockfd);
|
SSL_set_fd(ssl, sockfd);
|
||||||
|
if (argc != 3)
|
||||||
CyaSSL_check_domain_name(ssl, "www.yassl.com");
|
CyaSSL_check_domain_name(ssl, "www.yassl.com");
|
||||||
#ifdef NON_BLOCKING
|
#ifdef NON_BLOCKING
|
||||||
tcp_set_nonblocking(&sockfd);
|
tcp_set_nonblocking(&sockfd);
|
||||||
|
@@ -619,6 +619,8 @@ void SSL_CtxResourceFree(SSL_CTX*);
|
|||||||
int DeriveTlsKeys(SSL* ssl);
|
int DeriveTlsKeys(SSL* ssl);
|
||||||
int ProcessOldClientHello(SSL* ssl, const byte* input, word32* inOutIdx,
|
int ProcessOldClientHello(SSL* ssl, const byte* input, word32* inOutIdx,
|
||||||
word32 inSz, word16 sz);
|
word32 inSz, word16 sz);
|
||||||
|
int AddCA(SSL_CTX* ctx, buffer der, SSL*);
|
||||||
|
int IsCA(SSL_CTX* ctx, byte* hash);
|
||||||
|
|
||||||
/* All cipher suite related info */
|
/* All cipher suite related info */
|
||||||
typedef struct CipherSpecs {
|
typedef struct CipherSpecs {
|
||||||
@@ -933,7 +935,8 @@ struct X509_NAME {
|
|||||||
struct X509 {
|
struct X509 {
|
||||||
X509_NAME issuer;
|
X509_NAME issuer;
|
||||||
X509_NAME subject;
|
X509_NAME subject;
|
||||||
byte serial[SERIAL_SIZE];
|
int serialSz;
|
||||||
|
byte serial[EXTERNAL_SERIAL_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -174,16 +174,17 @@ static INLINE void showPeer(SSL* ssl)
|
|||||||
if (peer) {
|
if (peer) {
|
||||||
char* issuer = X509_NAME_oneline(X509_get_issuer_name(peer), 0, 0);
|
char* issuer = X509_NAME_oneline(X509_get_issuer_name(peer), 0, 0);
|
||||||
char* subject = X509_NAME_oneline(X509_get_subject_name(peer), 0, 0);
|
char* subject = X509_NAME_oneline(X509_get_subject_name(peer), 0, 0);
|
||||||
byte serial[SERIAL_SZ];
|
byte serial[32];
|
||||||
int ret;
|
int ret;
|
||||||
|
int sz = sizeof(serial);
|
||||||
|
|
||||||
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);
|
||||||
ret = CyaSSL_X509_get_serial_number(peer, serial);
|
ret = CyaSSL_X509_get_serial_number(peer, serial, &sz);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
int i;
|
int i;
|
||||||
printf(" serial number");
|
printf(" serial number");
|
||||||
for (i = 0; i < sizeof(serial); i++)
|
for (i = 0; i < sz; i++)
|
||||||
printf(":%02x", serial[i]);
|
printf(":%02x", serial[i]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@@ -385,7 +385,6 @@ enum {
|
|||||||
OCSP_BASICRESP = 16,
|
OCSP_BASICRESP = 16,
|
||||||
|
|
||||||
ASN1_GENERALIZEDTIME = 4,
|
ASN1_GENERALIZEDTIME = 4,
|
||||||
SERIAL_SZ = 8,
|
|
||||||
|
|
||||||
SSL_OP_MICROSOFT_SESS_ID_BUG = 1,
|
SSL_OP_MICROSOFT_SESS_ID_BUG = 1,
|
||||||
SSL_OP_NETSCAPE_CHALLENGE_BUG = 2,
|
SSL_OP_NETSCAPE_CHALLENGE_BUG = 2,
|
||||||
@@ -624,7 +623,7 @@ unsigned char* CyaSSL_get_chain_cert(X509_CHAIN*, int idx); /* index cert */
|
|||||||
int CyaSSL_get_chain_cert_pem(X509_CHAIN*, int idx, unsigned char* buffer,
|
int CyaSSL_get_chain_cert_pem(X509_CHAIN*, int idx, unsigned char* buffer,
|
||||||
int inLen, int* outLen); /* get index cert in PEM */
|
int inLen, int* outLen); /* get index cert in PEM */
|
||||||
const unsigned char* CyaSSL_get_sessionID(const SSL_SESSION* session);
|
const unsigned char* CyaSSL_get_sessionID(const SSL_SESSION* session);
|
||||||
int CyaSSL_X509_get_serial_number(X509*, unsigned char*);
|
int CyaSSL_X509_get_serial_number(X509*, unsigned char*, int*);
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#ifndef NO_WRITEV
|
#ifndef NO_WRITEV
|
||||||
|
@@ -1391,7 +1391,10 @@ static int DoCertificate(SSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
int anyError = 0;
|
int anyError = 0;
|
||||||
int firstTime = 1; /* peer's is at front */
|
int firstTime = 1; /* peer's is at front */
|
||||||
|
int totalCerts = 0; /* number of certs in certs buffer */
|
||||||
|
int count;
|
||||||
char domain[ASN_NAME_MAX];
|
char domain[ASN_NAME_MAX];
|
||||||
|
buffer certs[MAX_CHAIN_DEPTH];
|
||||||
|
|
||||||
#ifdef CYASSL_CALLBACKS
|
#ifdef CYASSL_CALLBACKS
|
||||||
if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
|
if (ssl->hsInfoOn) AddPacketName("Certificate", &ssl->handShakeInfo);
|
||||||
@@ -1400,12 +1403,15 @@ static int DoCertificate(SSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
c24to32(&input[i], &listSz);
|
c24to32(&input[i], &listSz);
|
||||||
i += CERT_HEADER_SZ;
|
i += CERT_HEADER_SZ;
|
||||||
|
|
||||||
|
CYASSL_MSG("Loading peer's cert chain");
|
||||||
|
/* first put cert chain into buffer so can verify top down
|
||||||
|
we're sent bottom up */
|
||||||
while (listSz) {
|
while (listSz) {
|
||||||
/* cert size */
|
/* cert size */
|
||||||
buffer myCert;
|
|
||||||
word32 certSz;
|
word32 certSz;
|
||||||
DecodedCert dCert;
|
|
||||||
word32 idx = 0;
|
if (totalCerts >= MAX_CHAIN_DEPTH)
|
||||||
|
return BUFFER_E;
|
||||||
|
|
||||||
c24to32(&input[i], &certSz);
|
c24to32(&input[i], &certSz);
|
||||||
i += CERT_HEADER_SZ;
|
i += CERT_HEADER_SZ;
|
||||||
@@ -1413,49 +1419,70 @@ static int DoCertificate(SSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
if (listSz > MAX_RECORD_SIZE || certSz > MAX_RECORD_SIZE)
|
if (listSz > MAX_RECORD_SIZE || certSz > MAX_RECORD_SIZE)
|
||||||
return BUFFER_E;
|
return BUFFER_E;
|
||||||
|
|
||||||
myCert.length = certSz;
|
certs[totalCerts].length = certSz;
|
||||||
myCert.buffer = input + i;
|
certs[totalCerts].buffer = input + i;
|
||||||
i += certSz;
|
|
||||||
|
|
||||||
listSz -= certSz + CERT_HEADER_SZ;
|
|
||||||
|
|
||||||
if (ret != 0 && anyError == 0)
|
|
||||||
anyError = ret; /* save error from last time */
|
|
||||||
|
|
||||||
#ifdef SESSION_CERTS
|
#ifdef SESSION_CERTS
|
||||||
if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
|
if (ssl->session.chain.count < MAX_CHAIN_DEPTH &&
|
||||||
myCert.length < MAX_X509_SIZE) {
|
certSz < MAX_X509_SIZE) {
|
||||||
ssl->session.chain.certs[ssl->session.chain.count].length =
|
ssl->session.chain.certs[ssl->session.chain.count].length = certSz;
|
||||||
myCert.length;
|
|
||||||
XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
|
XMEMCPY(ssl->session.chain.certs[ssl->session.chain.count].buffer,
|
||||||
myCert.buffer, myCert.length);
|
input + i, certSz);
|
||||||
ssl->session.chain.count++;
|
ssl->session.chain.count++;
|
||||||
} else {
|
} else {
|
||||||
CYASSL_MSG("Couldn't store chain cert for session");
|
CYASSL_MSG("Couldn't store chain cert for session");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
i += certSz;
|
||||||
|
listSz -= certSz + CERT_HEADER_SZ;
|
||||||
|
|
||||||
|
totalCerts++;
|
||||||
|
CYASSL_MSG(" Put another cert into chain");
|
||||||
|
}
|
||||||
|
|
||||||
|
count = totalCerts;
|
||||||
|
|
||||||
|
/* verify up to peer's first */
|
||||||
|
while (count > 1) {
|
||||||
|
buffer myCert = certs[count - 1];
|
||||||
|
DecodedCert dCert;
|
||||||
|
|
||||||
InitDecodedCert(&dCert, myCert.buffer, ssl->heap);
|
InitDecodedCert(&dCert, myCert.buffer, ssl->heap);
|
||||||
ret = ParseCertRelative(&dCert, myCert.length, CERT_TYPE,
|
ret = ParseCertRelative(&dCert, myCert.length, CERT_TYPE,
|
||||||
!ssl->options.verifyNone, ssl->caList);
|
!ssl->options.verifyNone, ssl->caList);
|
||||||
|
if (ret == 0 && !IsCA(ssl->ctx, dCert.subjectHash)) {
|
||||||
|
buffer add;
|
||||||
|
add.length = myCert.length;
|
||||||
|
add.buffer = (byte*)XMALLOC(myCert.length, ssl->heap,
|
||||||
|
DYNAMIC_TYPE_CA);
|
||||||
|
CYASSL_MSG("Adding CA from chain");
|
||||||
|
|
||||||
|
if (add.buffer == NULL)
|
||||||
|
return MEMORY_E;
|
||||||
|
XMEMCPY(add.buffer, myCert.buffer, myCert.length);
|
||||||
|
|
||||||
|
ret = AddCA(ssl->ctx, add, ssl);
|
||||||
|
if (ret == 1) ret = 0; /* SSL_SUCCESS for external */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != 0 && anyError == 0)
|
||||||
|
anyError = ret; /* save error from last time */
|
||||||
|
|
||||||
if (!firstTime) {
|
|
||||||
FreeDecodedCert(&dCert);
|
FreeDecodedCert(&dCert);
|
||||||
continue;
|
count--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get rest of peer info in case user wants to continue */
|
/* peer's, may not have one if blank client cert sent by TLSv1.2 */
|
||||||
if (ret != 0) {
|
if (count) {
|
||||||
if (!(ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E ||
|
buffer myCert = certs[0];
|
||||||
ret == ASN_SIG_CONFIRM_E)) {
|
DecodedCert dCert;
|
||||||
FreeDecodedCert(&dCert);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* first one has peer's key */
|
CYASSL_MSG("Veriying Peer's cert");
|
||||||
firstTime = 0;
|
|
||||||
|
|
||||||
|
InitDecodedCert(&dCert, myCert.buffer, ssl->heap);
|
||||||
|
ret = ParseCertRelative(&dCert, myCert.length, CERT_TYPE,
|
||||||
|
!ssl->options.verifyNone, ssl->caList);
|
||||||
ssl->options.havePeerCert = 1;
|
ssl->options.havePeerCert = 1;
|
||||||
/* set X509 format */
|
/* set X509 format */
|
||||||
#ifdef OPENSSL_EXTRA
|
#ifdef OPENSSL_EXTRA
|
||||||
@@ -1463,7 +1490,8 @@ static int DoCertificate(SSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
XSTRNCPY(ssl->peerCert.issuer.name, dCert.issuer, ASN_NAME_MAX);
|
XSTRNCPY(ssl->peerCert.issuer.name, dCert.issuer, ASN_NAME_MAX);
|
||||||
ssl->peerCert.subject.sz = (int)XSTRLEN(dCert.subject) + 1;
|
ssl->peerCert.subject.sz = (int)XSTRLEN(dCert.subject) + 1;
|
||||||
XSTRNCPY(ssl->peerCert.subject.name, dCert.subject, ASN_NAME_MAX);
|
XSTRNCPY(ssl->peerCert.subject.name, dCert.subject, ASN_NAME_MAX);
|
||||||
XMEMCPY(ssl->peerCert.serial, dCert.serial, SERIAL_SIZE);
|
XMEMCPY(ssl->peerCert.serial, dCert.serial, EXTERNAL_SERIAL_SIZE);
|
||||||
|
ssl->peerCert.serialSz = dCert.serialSz;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
XMEMCPY(domain, dCert.subjectCN, dCert.subjectCNLen);
|
XMEMCPY(domain, dCert.subjectCN, dCert.subjectCNLen);
|
||||||
@@ -1478,11 +1506,10 @@ static int DoCertificate(SSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
|
|
||||||
/* decode peer key */
|
/* decode peer key */
|
||||||
if (dCert.keyOID == RSAk) {
|
if (dCert.keyOID == RSAk) {
|
||||||
|
word32 idx = 0;
|
||||||
if (RsaPublicKeyDecode(dCert.publicKey, &idx,
|
if (RsaPublicKeyDecode(dCert.publicKey, &idx,
|
||||||
&ssl->peerRsaKey, dCert.pubKeySize) != 0) {
|
&ssl->peerRsaKey, dCert.pubKeySize) != 0) {
|
||||||
ret = PEER_KEY_ERROR;
|
ret = PEER_KEY_ERROR;
|
||||||
FreeDecodedCert(&dCert);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
ssl->peerRsaKeyPresent = 1;
|
ssl->peerRsaKeyPresent = 1;
|
||||||
}
|
}
|
||||||
@@ -1490,8 +1517,6 @@ static int DoCertificate(SSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
else if (dCert.keyOID == NTRUk) {
|
else if (dCert.keyOID == NTRUk) {
|
||||||
if (dCert.pubKeySize > sizeof(ssl->peerNtruKey)) {
|
if (dCert.pubKeySize > sizeof(ssl->peerNtruKey)) {
|
||||||
ret = PEER_KEY_ERROR;
|
ret = PEER_KEY_ERROR;
|
||||||
FreeDecodedCert(&dCert);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
XMEMCPY(ssl->peerNtruKey, dCert.publicKey, dCert.pubKeySize);
|
XMEMCPY(ssl->peerNtruKey, dCert.publicKey, dCert.pubKeySize);
|
||||||
ssl->peerNtruKeyLen = (word16)dCert.pubKeySize;
|
ssl->peerNtruKeyLen = (word16)dCert.pubKeySize;
|
||||||
@@ -1503,8 +1528,6 @@ static int DoCertificate(SSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
if (ecc_import_x963(dCert.publicKey, dCert.pubKeySize,
|
if (ecc_import_x963(dCert.publicKey, dCert.pubKeySize,
|
||||||
&ssl->peerEccDsaKey) != 0) {
|
&ssl->peerEccDsaKey) != 0) {
|
||||||
ret = PEER_KEY_ERROR;
|
ret = PEER_KEY_ERROR;
|
||||||
FreeDecodedCert(&dCert);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
ssl->peerEccDsaKeyPresent = 1;
|
ssl->peerEccDsaKeyPresent = 1;
|
||||||
}
|
}
|
||||||
@@ -1513,7 +1536,7 @@ static int DoCertificate(SSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
FreeDecodedCert(&dCert);
|
FreeDecodedCert(&dCert);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyError != 0)
|
if (anyError != 0 && ret == 0)
|
||||||
ret = anyError;
|
ret = anyError;
|
||||||
|
|
||||||
if (ret == 0 && ssl->options.side == CLIENT_END)
|
if (ret == 0 && ssl->options.side == CLIENT_END)
|
||||||
|
108
src/ssl.c
108
src/ssl.c
@@ -290,15 +290,61 @@ int SSL_pending(SSL* ssl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* owns der */
|
static CyaSSL_Mutex ca_mutex; /* CA signers mutex */
|
||||||
static int AddCA(SSL_CTX* ctx, buffer der)
|
|
||||||
|
/* does CA already exist on list */
|
||||||
|
int IsCA(SSL_CTX* ctx, byte* hash)
|
||||||
|
{
|
||||||
|
Signer* signers;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (LockMutex(&ca_mutex) != 0)
|
||||||
|
return ret;
|
||||||
|
signers = ctx->caList;
|
||||||
|
while (signers) {
|
||||||
|
if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
|
||||||
|
ret = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
signers = signers->next;
|
||||||
|
}
|
||||||
|
UnLockMutex(&ca_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* return CA if found, otherwise NULL */
|
||||||
|
Signer* GetCA(Signer* signers, byte* hash)
|
||||||
|
{
|
||||||
|
Signer* ret = 0;
|
||||||
|
|
||||||
|
if (LockMutex(&ca_mutex) != 0)
|
||||||
|
return ret;
|
||||||
|
while (signers) {
|
||||||
|
if (XMEMCMP(hash, signers->hash, SHA_DIGEST_SIZE) == 0) {
|
||||||
|
ret = signers;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
signers = signers->next;
|
||||||
|
}
|
||||||
|
UnLockMutex(&ca_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* owns der, cyassl_int now uses too */
|
||||||
|
int AddCA(SSL_CTX* ctx, buffer der, SSL* ssl)
|
||||||
{
|
{
|
||||||
word32 ret;
|
word32 ret;
|
||||||
DecodedCert cert;
|
DecodedCert cert;
|
||||||
Signer* signer = 0;
|
Signer* signer = 0;
|
||||||
|
|
||||||
|
CYASSL_MSG("Adding a CA");
|
||||||
InitDecodedCert(&cert, der.buffer, ctx->heap);
|
InitDecodedCert(&cert, der.buffer, ctx->heap);
|
||||||
ret = ParseCert(&cert, der.length, CA_TYPE, ctx->verifyPeer, 0);
|
ret = ParseCert(&cert, der.length, CA_TYPE, ctx->verifyPeer, 0);
|
||||||
|
CYASSL_MSG(" Parsed new CA");
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
/* take over signer parts */
|
/* take over signer parts */
|
||||||
@@ -315,13 +361,23 @@ static int AddCA(SSL_CTX* ctx, buffer der)
|
|||||||
cert.publicKey = 0; /* don't free here */
|
cert.publicKey = 0; /* don't free here */
|
||||||
cert.subjectCN = 0;
|
cert.subjectCN = 0;
|
||||||
|
|
||||||
|
if (LockMutex(&ca_mutex) == 0) {
|
||||||
signer->next = ctx->caList;
|
signer->next = ctx->caList;
|
||||||
ctx->caList = signer; /* takes ownership */
|
ctx->caList = signer; /* takes ownership */
|
||||||
|
if (ssl)
|
||||||
|
ssl->caList = ctx->caList;
|
||||||
|
UnLockMutex(&ca_mutex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FreeSigners(signer, ctx->heap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CYASSL_MSG(" Freeing Parsed CA");
|
||||||
FreeDecodedCert(&cert);
|
FreeDecodedCert(&cert);
|
||||||
|
CYASSL_MSG(" Freeing der CA");
|
||||||
XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_CA);
|
XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_CA);
|
||||||
|
CYASSL_MSG(" OK Freeing der CA");
|
||||||
|
|
||||||
if (ret == 0) return SSL_SUCCESS;
|
if (ret == 0) return SSL_SUCCESS;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -359,7 +415,7 @@ static int AddCA(SSL_CTX* ctx, buffer der)
|
|||||||
|
|
||||||
static SessionRow SessionCache[SESSION_ROWS];
|
static SessionRow SessionCache[SESSION_ROWS];
|
||||||
|
|
||||||
static CyaSSL_Mutex mutex; /* SessionCache mutex */
|
static CyaSSL_Mutex session_mutex; /* SessionCache mutex */
|
||||||
|
|
||||||
#endif /* NO_SESSION_CACHE */
|
#endif /* NO_SESSION_CACHE */
|
||||||
|
|
||||||
@@ -663,7 +719,7 @@ static int AddCA(SSL_CTX* ctx, buffer der)
|
|||||||
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
|
#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */
|
||||||
|
|
||||||
if (type == CA_TYPE)
|
if (type == CA_TYPE)
|
||||||
return AddCA(ctx, der); /* takes der over */
|
return AddCA(ctx, der, ssl); /* takes der over */
|
||||||
else if (type == CERT_TYPE) {
|
else if (type == CERT_TYPE) {
|
||||||
if (ssl) {
|
if (ssl) {
|
||||||
if (ssl->buffers.weOwnCert && ssl->buffers.certificate.buffer)
|
if (ssl->buffers.weOwnCert && ssl->buffers.certificate.buffer)
|
||||||
@@ -800,6 +856,7 @@ static int ProcessFile(SSL_CTX* ctx, const char* fname, int format, int type,
|
|||||||
XREWIND(file);
|
XREWIND(file);
|
||||||
|
|
||||||
if (sz > (long)sizeof(staticBuffer)) {
|
if (sz > (long)sizeof(staticBuffer)) {
|
||||||
|
CYASSL_MSG("Getting dynamic buffer");
|
||||||
buffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
|
buffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
XFCLOSE(file);
|
XFCLOSE(file);
|
||||||
@@ -1488,27 +1545,29 @@ int SSL_CTX_set_cipher_list(SSL_CTX* ctx, const char* list)
|
|||||||
|
|
||||||
int InitCyaSSL(void)
|
int InitCyaSSL(void)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
#ifndef NO_SESSION_CACHE
|
#ifndef NO_SESSION_CACHE
|
||||||
if (InitMutex(&mutex) == 0)
|
if (InitMutex(&session_mutex) != 0)
|
||||||
return 0;
|
ret = -1;
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
if (InitMutex(&ca_mutex) != 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int FreeCyaSSL(void)
|
int FreeCyaSSL(void)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
#ifndef NO_SESSION_CACHE
|
#ifndef NO_SESSION_CACHE
|
||||||
if (FreeMutex(&mutex) == 0)
|
if (FreeMutex(&session_mutex) != 0)
|
||||||
return 0;
|
ret = -1;
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
#endif
|
||||||
|
if (FreeMutex(&ca_mutex) != 0)
|
||||||
|
ret = -1;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1541,7 +1600,7 @@ SSL_SESSION* GetSession(SSL* ssl, byte* masterSecret)
|
|||||||
|
|
||||||
row = HashSession(id) % SESSION_ROWS;
|
row = HashSession(id) % SESSION_ROWS;
|
||||||
|
|
||||||
if (LockMutex(&mutex) != 0)
|
if (LockMutex(&session_mutex) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (SessionCache[row].totalCount >= SESSIONS_PER_ROW)
|
if (SessionCache[row].totalCount >= SESSIONS_PER_ROW)
|
||||||
@@ -1566,7 +1625,7 @@ SSL_SESSION* GetSession(SSL* ssl, byte* masterSecret)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UnLockMutex(&mutex);
|
UnLockMutex(&session_mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -1602,7 +1661,7 @@ int AddSession(SSL* ssl)
|
|||||||
|
|
||||||
row = HashSession(ssl->arrays.sessionID) % SESSION_ROWS;
|
row = HashSession(ssl->arrays.sessionID) % SESSION_ROWS;
|
||||||
|
|
||||||
if (LockMutex(&mutex) != 0)
|
if (LockMutex(&session_mutex) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
idx = SessionCache[row].nextIdx++;
|
idx = SessionCache[row].nextIdx++;
|
||||||
@@ -1629,7 +1688,7 @@ int AddSession(SSL* ssl)
|
|||||||
if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
|
if (SessionCache[row].nextIdx == SESSIONS_PER_ROW)
|
||||||
SessionCache[row].nextIdx = 0;
|
SessionCache[row].nextIdx = 0;
|
||||||
|
|
||||||
if (UnLockMutex(&mutex) != 0)
|
if (UnLockMutex(&session_mutex) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -3619,14 +3678,15 @@ int CyaSSL_set_compression(SSL* ssl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* write X509 serial number in unsigned binary to buffer
|
/* write X509 serial number in unsigned binary to buffer
|
||||||
buffer needs to be at least SERIAL_SIZE
|
buffer needs to be at least EXTERNAL_SERIAL_SIZE (32) for all cases
|
||||||
return 0 on success */
|
return 0 on success */
|
||||||
int CyaSSL_X509_get_serial_number(X509* x509, byte* buffer)
|
int CyaSSL_X509_get_serial_number(X509* x509, byte* buffer, int* inOutSz)
|
||||||
{
|
{
|
||||||
if (x509 == NULL || buffer == NULL)
|
if (x509 == NULL || buffer == NULL || *inOutSz < x509->serialSz)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
XMEMCPY(buffer, x509->serial, SERIAL_SIZE);
|
XMEMCPY(buffer, x509->serial, x509->serialSz);
|
||||||
|
*inOutSz = x509->serialSz;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user