Merge branch 'master' of github.com:cyassl/cyassl
Conflicts: ctaocrypt/test/test.c cyassl/ctaocrypt/pkcs7.h
This commit is contained in:
commit
85c5c29e7a
@ -439,8 +439,8 @@ CYASSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
|
||||
}
|
||||
|
||||
|
||||
static int GetSequence(const byte* input, word32* inOutIdx, int* len,
|
||||
word32 maxIdx)
|
||||
CYASSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
|
||||
word32 maxIdx)
|
||||
{
|
||||
int length = -1;
|
||||
word32 idx = *inOutIdx;
|
||||
@ -456,7 +456,8 @@ static int GetSequence(const byte* input, word32* inOutIdx, int* len,
|
||||
}
|
||||
|
||||
|
||||
static int GetSet(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
|
||||
CYASSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
|
||||
word32 maxIdx)
|
||||
{
|
||||
int length = -1;
|
||||
word32 idx = *inOutIdx;
|
||||
@ -473,7 +474,7 @@ static int GetSet(const byte* input, word32* inOutIdx, int* len, word32 maxIdx)
|
||||
|
||||
|
||||
/* winodws header clash for WinCE using GetVersion */
|
||||
static int GetMyVersion(const byte* input, word32* inOutIdx, int* version)
|
||||
CYASSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx, int* version)
|
||||
{
|
||||
word32 idx = *inOutIdx;
|
||||
|
||||
@ -537,7 +538,7 @@ static int GetExplicitVersion(const byte* input, word32* inOutIdx, int* version)
|
||||
}
|
||||
|
||||
|
||||
static int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,
|
||||
CYASSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,
|
||||
word32 maxIdx)
|
||||
{
|
||||
word32 i = *inOutIdx;
|
||||
@ -593,7 +594,7 @@ static int GetObjectId(const byte* input, word32* inOutIdx, word32* oid,
|
||||
}
|
||||
|
||||
|
||||
static int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
|
||||
CYASSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
|
||||
word32 maxIdx)
|
||||
{
|
||||
int length;
|
||||
@ -6064,39 +6065,9 @@ int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HAVE_CRL
|
||||
|
||||
/* initialize decoded CRL */
|
||||
void InitDecodedCRL(DecodedCRL* dcrl)
|
||||
{
|
||||
CYASSL_MSG("InitDecodedCRL");
|
||||
|
||||
dcrl->certBegin = 0;
|
||||
dcrl->sigIndex = 0;
|
||||
dcrl->sigLength = 0;
|
||||
dcrl->signatureOID = 0;
|
||||
dcrl->certs = NULL;
|
||||
dcrl->totalCerts = 0;
|
||||
}
|
||||
|
||||
|
||||
/* free decoded CRL resources */
|
||||
void FreeDecodedCRL(DecodedCRL* dcrl)
|
||||
{
|
||||
RevokedCert* tmp = dcrl->certs;
|
||||
|
||||
CYASSL_MSG("FreeDecodedCRL");
|
||||
|
||||
while(tmp) {
|
||||
RevokedCert* next = tmp->next;
|
||||
XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
|
||||
tmp = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* store SHA1 hash of NAME */
|
||||
static int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx)
|
||||
CYASSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
|
||||
int maxIdx)
|
||||
{
|
||||
Sha sha;
|
||||
int length; /* length of all distinguished names */
|
||||
@ -6131,6 +6102,37 @@ static int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx)
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_CRL
|
||||
|
||||
/* initialize decoded CRL */
|
||||
void InitDecodedCRL(DecodedCRL* dcrl)
|
||||
{
|
||||
CYASSL_MSG("InitDecodedCRL");
|
||||
|
||||
dcrl->certBegin = 0;
|
||||
dcrl->sigIndex = 0;
|
||||
dcrl->sigLength = 0;
|
||||
dcrl->signatureOID = 0;
|
||||
dcrl->certs = NULL;
|
||||
dcrl->totalCerts = 0;
|
||||
}
|
||||
|
||||
|
||||
/* free decoded CRL resources */
|
||||
void FreeDecodedCRL(DecodedCRL* dcrl)
|
||||
{
|
||||
RevokedCert* tmp = dcrl->certs;
|
||||
|
||||
CYASSL_MSG("FreeDecodedCRL");
|
||||
|
||||
while(tmp) {
|
||||
RevokedCert* next = tmp->next;
|
||||
XFREE(tmp, NULL, DYNAMIC_TYPE_REVOKED);
|
||||
tmp = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get Revoked Cert list, 0 on success */
|
||||
static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
|
||||
int maxIdx)
|
||||
|
@ -147,10 +147,87 @@ const byte base64Encode[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||
};
|
||||
|
||||
|
||||
/* make sure *i (idx) won't exceed max, store and possibly escape to out,
|
||||
* raw means use e w/o decode, 0 on success */
|
||||
static int Escape(int escaped, byte e, byte* out, word32* i, word32 max,
|
||||
int raw)
|
||||
{
|
||||
int doEscape = 0;
|
||||
word32 needed = 1;
|
||||
word32 idx = *i;
|
||||
|
||||
byte basic;
|
||||
byte plus = 0;
|
||||
byte equals = 0;
|
||||
byte newline = 0;
|
||||
|
||||
if (raw)
|
||||
basic = e;
|
||||
else
|
||||
basic = base64Encode[e];
|
||||
|
||||
/* check whether to escape */
|
||||
if (escaped) {
|
||||
switch ((char)basic) {
|
||||
case '+' :
|
||||
plus = 1;
|
||||
doEscape = 1;
|
||||
needed += 2;
|
||||
break;
|
||||
case '=' :
|
||||
equals = 1;
|
||||
doEscape = 1;
|
||||
needed += 2;
|
||||
break;
|
||||
case '\n' :
|
||||
newline = 1;
|
||||
doEscape = 1;
|
||||
needed += 2;
|
||||
break;
|
||||
default:
|
||||
/* do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check size */
|
||||
if ( (idx+needed) > max) {
|
||||
CYASSL_MSG("Escape buffer max too small");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
/* store it */
|
||||
if (doEscape == 0) {
|
||||
out[idx++] = basic;
|
||||
}
|
||||
else {
|
||||
out[idx++] = '%'; /* start escape */
|
||||
|
||||
if (plus) {
|
||||
out[idx++] = '2';
|
||||
out[idx++] = 'B';
|
||||
}
|
||||
else if (equals) {
|
||||
out[idx++] = '3';
|
||||
out[idx++] = 'D';
|
||||
}
|
||||
else if (newline) {
|
||||
out[idx++] = '0';
|
||||
out[idx++] = 'A';
|
||||
}
|
||||
|
||||
}
|
||||
*i = idx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* internal worker, handles both escaped and normal line endings */
|
||||
static int DoBase64_Encode(const byte* in, word32 inLen, byte* out,
|
||||
word32* outLen, int escaped)
|
||||
{
|
||||
int ret = 0;
|
||||
word32 i = 0,
|
||||
j = 0,
|
||||
n = 0; /* new line counter */
|
||||
@ -163,6 +240,8 @@ static int DoBase64_Encode(const byte* in, word32 inLen, byte* out,
|
||||
|
||||
outSz += addSz;
|
||||
|
||||
/* if escaped we can't predetermine size for one pass encoding, but
|
||||
* make sure we have enough if no escapes are in input */
|
||||
if (outSz > *outLen) return BAD_FUNC_ARG;
|
||||
|
||||
while (inLen > 2) {
|
||||
@ -177,26 +256,25 @@ static int DoBase64_Encode(const byte* in, word32 inLen, byte* out,
|
||||
byte e4 = b3 & 0x3F;
|
||||
|
||||
/* store */
|
||||
out[i++] = base64Encode[e1];
|
||||
out[i++] = base64Encode[e2];
|
||||
out[i++] = base64Encode[e3];
|
||||
out[i++] = base64Encode[e4];
|
||||
ret = Escape(escaped, e1, out, &i, *outLen, 0);
|
||||
if (ret != 0) break;
|
||||
ret = Escape(escaped, e2, out, &i, *outLen, 0);
|
||||
if (ret != 0) break;
|
||||
ret = Escape(escaped, e3, out, &i, *outLen, 0);
|
||||
if (ret != 0) break;
|
||||
ret = Escape(escaped, e4, out, &i, *outLen, 0);
|
||||
if (ret != 0) break;
|
||||
|
||||
inLen -= 3;
|
||||
|
||||
if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen) {
|
||||
if (escaped) {
|
||||
out[i++] = '%';
|
||||
out[i++] = '0';
|
||||
out[i++] = 'A';
|
||||
}
|
||||
else
|
||||
out[i++] = '\n';
|
||||
ret = Escape(escaped, '\n', out, &i, *outLen, 1);
|
||||
if (ret != 0) break;
|
||||
}
|
||||
}
|
||||
|
||||
/* last integral */
|
||||
if (inLen) {
|
||||
if (inLen && ret == 0) {
|
||||
int twoBytes = (inLen == 2);
|
||||
|
||||
byte b1 = in[j++];
|
||||
@ -206,24 +284,29 @@ static int DoBase64_Encode(const byte* in, word32 inLen, byte* out,
|
||||
byte e2 = ((b1 & 0x3) << 4) | (b2 >> 4);
|
||||
byte e3 = (b2 & 0xF) << 2;
|
||||
|
||||
out[i++] = base64Encode[e1];
|
||||
out[i++] = base64Encode[e2];
|
||||
out[i++] = (twoBytes) ? base64Encode[e3] : PAD;
|
||||
out[i++] = PAD;
|
||||
ret = Escape(escaped, e1, out, &i, *outLen, 0);
|
||||
if (ret == 0)
|
||||
ret = Escape(escaped, e2, out, &i, *outLen, 0);
|
||||
if (ret == 0) {
|
||||
/* third */
|
||||
if (twoBytes)
|
||||
ret = Escape(escaped, e3, out, &i, *outLen, 0);
|
||||
else
|
||||
ret = Escape(escaped, '=', out, &i, *outLen, 1);
|
||||
}
|
||||
/* fourth always pad */
|
||||
if (ret == 0)
|
||||
ret = Escape(escaped, '=', out, &i, *outLen, 1);
|
||||
}
|
||||
|
||||
if (escaped) {
|
||||
out[i++] = '%';
|
||||
out[i++] = '0';
|
||||
out[i++] = 'A';
|
||||
}
|
||||
else
|
||||
out[i++] = '\n';
|
||||
if (i != outSz)
|
||||
return ASN_INPUT_E;
|
||||
*outLen = outSz;
|
||||
if (ret == 0)
|
||||
ret = Escape(escaped, '\n', out, &i, *outLen, 1);
|
||||
|
||||
return 0;
|
||||
if (i != outSz && escaped == 0 && ret == 0)
|
||||
return ASN_INPUT_E;
|
||||
|
||||
*outLen = i;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -335,6 +335,14 @@ void CTaoCryptErrorString(int error, char* buffer)
|
||||
XSTRNCPY(buffer, "Setting cert request attributes error", max);
|
||||
break;
|
||||
|
||||
case PKCS7_OID_E:
|
||||
XSTRNCPY(buffer, "PKCS#7 error: mismatched OID value", max);
|
||||
break;
|
||||
|
||||
case PKCS7_RECIP_E:
|
||||
XSTRNCPY(buffer, "PKCS#7 error: no matching recipient found", max);
|
||||
break;
|
||||
|
||||
default:
|
||||
XSTRNCPY(buffer, "unknown error number", max);
|
||||
|
||||
|
@ -114,6 +114,33 @@ CYASSL_LOCAL int SetContentType(int pkcs7TypeOID, byte* output)
|
||||
|
||||
}
|
||||
|
||||
int GetContentType(const byte* input, word32* inOutIdx, word32* oid,
|
||||
word32 maxIdx)
|
||||
{
|
||||
int length;
|
||||
word32 i = *inOutIdx;
|
||||
byte b;
|
||||
*oid = 0;
|
||||
|
||||
CYASSL_ENTER("GetContentType");
|
||||
|
||||
b = input[i++];
|
||||
if (b != ASN_OBJECT_ID)
|
||||
return ASN_OBJECT_ID_E;
|
||||
|
||||
if (GetLength(input, &i, &length, maxIdx) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
while(length--) {
|
||||
*oid += input[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
*inOutIdx = i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PKCS7_InitWithCert(PKCS7* pkcs7, byte* cert, word32 certSz)
|
||||
{
|
||||
@ -556,6 +583,8 @@ CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz,
|
||||
return ALGO_ID_E;
|
||||
|
||||
keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, keyType, 0);
|
||||
if (keyEncAlgSz == 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* EncryptedKey */
|
||||
InitRsaKey(&pubKey, 0);
|
||||
@ -642,6 +671,13 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
byte contentEncAlgo[MAX_ALGO_SZ];
|
||||
byte encContentOctet[MAX_OCTET_STR_SZ];
|
||||
|
||||
if (pkcs7 == NULL || pkcs7->content == NULL || pkcs7->contentSz == 0 ||
|
||||
pkcs7->encryptOID == 0 || pkcs7->singleCert == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (output == NULL || outputSz == 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
switch (pkcs7->encryptOID) {
|
||||
case DESb:
|
||||
blockKeySz = DES_KEYLEN;
|
||||
@ -662,7 +698,7 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
/* version */
|
||||
verSz = SetMyVersion(0, ver, 0);
|
||||
|
||||
/* generate random content enc key */
|
||||
/* generate random content encryption key */
|
||||
InitRng(&rng);
|
||||
RNG_GenerateBlock(&rng, contentKeyPlain, blockKeySz);
|
||||
|
||||
@ -680,8 +716,13 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
|
||||
/* EncryptedContentInfo */
|
||||
contentTypeSz = SetContentType(pkcs7->contentOID, contentType);
|
||||
if (contentTypeSz == 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
|
||||
blkType, 0);
|
||||
if (contentEncAlgoSz == 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* allocate memory for encrypted content, pad if necessary */
|
||||
padSz = DES_BLOCK_SIZE - (pkcs7->contentSz % DES_BLOCK_SIZE);
|
||||
@ -696,7 +737,7 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
dynamicFlag = 1;
|
||||
|
||||
for (i = 0; i < padSz; i++) {
|
||||
plain[pkcs7->contentSz + i + 1] = padSz;
|
||||
plain[pkcs7->contentSz + i] = padSz;
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -711,16 +752,17 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
/* use NULL iv for now */
|
||||
byte tmpIv[blockKeySz];
|
||||
XMEMSET(tmpIv, 0, sizeof(tmpIv));
|
||||
|
||||
if (pkcs7->encryptOID == DESb) {
|
||||
Des des;
|
||||
RNG_GenerateBlock(&rng, tmpIv, (word32)sizeof(tmpIv));
|
||||
Des_SetKey(&des, contentKeyPlain, tmpIv, DES_ENCRYPTION);
|
||||
Des_CbcEncrypt(&des, encryptedContent, plain, desOutSz);
|
||||
|
||||
} else if (pkcs7->encryptOID == DES3b) {
|
||||
Des3 des3;
|
||||
RNG_GenerateBlock(&rng, tmpIv, (word32)sizeof(tmpIv));
|
||||
Des3_SetKey(&des3, contentKeyPlain, tmpIv, DES_ENCRYPTION);
|
||||
Des3_CbcEncrypt(&des3, encryptedContent, plain, desOutSz);
|
||||
}
|
||||
@ -784,6 +826,10 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
#ifdef NO_RC4
|
||||
FreeRng(&rng);
|
||||
#endif
|
||||
|
||||
XMEMSET(contentKeyPlain, 0, MAX_CONTENT_KEY_LEN);
|
||||
XMEMSET(contentKeyEnc, 0, MAX_ENCRYPTED_KEY_SZ);
|
||||
|
||||
if (dynamicFlag)
|
||||
XFREE(plain, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
@ -791,6 +837,219 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
||||
return idx;
|
||||
}
|
||||
|
||||
CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
||||
word32 pkiMsgSz, byte* output,
|
||||
word32 outputSz)
|
||||
{
|
||||
int recipFound = 0;
|
||||
int ret, version, length;
|
||||
word32 savedIdx = 0, idx = 0;
|
||||
word32 contentType, encOID;
|
||||
byte issuerHash[SHA_DIGEST_SIZE];
|
||||
mp_int serialNum;
|
||||
|
||||
DecodedCert decoded;
|
||||
|
||||
int encryptedKeySz, keySz;
|
||||
byte tmpIv[DES3_KEYLEN];
|
||||
byte encryptedKey[MAX_ENCRYPTED_KEY_SZ];
|
||||
byte* decryptedKey = NULL;
|
||||
|
||||
RsaKey privKey;
|
||||
int encryptedContentSz;
|
||||
byte padLen;
|
||||
byte* encryptedContent = NULL;
|
||||
|
||||
if (pkcs7 == NULL || pkcs7->singleCert == NULL ||
|
||||
pkcs7->singleCertSz == 0 || pkcs7->privateKey == NULL ||
|
||||
pkcs7->privKeySize == 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (pkiMsg == NULL || pkiMsgSz == 0 ||
|
||||
output == NULL || outputSz == 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* parse recipient cert */
|
||||
InitDecodedCert(&decoded, pkcs7->singleCert, pkcs7->singleCertSz, 0);
|
||||
ret = ParseCert(&decoded, CA_TYPE, NO_VERIFY, 0);
|
||||
if (ret < 0) {
|
||||
FreeDecodedCert(&decoded);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* load private key */
|
||||
InitRsaKey(&privKey, 0);
|
||||
ret = RsaPrivateKeyDecode(pkcs7->privateKey, &idx, &privKey,
|
||||
pkcs7->privKeySize);
|
||||
if (ret != 0) {
|
||||
CYASSL_MSG("Failed to decode RSA private key");
|
||||
return ret;
|
||||
}
|
||||
|
||||
idx = 0;
|
||||
|
||||
/* read past ContentInfo, verify type */
|
||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (contentType != ENVELOPED_DATA) {
|
||||
CYASSL_MSG("PKCS#7 input not of type EnvelopedData");
|
||||
return PKCS7_OID_E;
|
||||
}
|
||||
|
||||
if (pkiMsg[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0))
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* remove EnvelopedData */
|
||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetMyVersion(pkiMsg, &idx, &version) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (version != 0) {
|
||||
CYASSL_MSG("PKCS#7 envelopedData needs to be of version 0");
|
||||
return ASN_VERSION_E;
|
||||
}
|
||||
|
||||
/* walk through RecipientInfo set, find correct recipient */
|
||||
if (GetSet(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
savedIdx = idx;
|
||||
recipFound = 0;
|
||||
|
||||
/* when looking for next recipient, use first sequence and version to
|
||||
* indicate there is another, if not, move on */
|
||||
while(recipFound == 0) {
|
||||
|
||||
/* remove RecipientInfo */
|
||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) {
|
||||
if (recipFound == 0) {
|
||||
return ASN_PARSE_E;
|
||||
} else {
|
||||
idx = savedIdx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetMyVersion(pkiMsg, &idx, &version) < 0) {
|
||||
if (recipFound == 0) {
|
||||
return ASN_PARSE_E;
|
||||
} else {
|
||||
idx = savedIdx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (version != 0)
|
||||
return ASN_VERSION_E;
|
||||
|
||||
/* remove IssuerAndSerialNumber */
|
||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetNameHash(pkiMsg, &idx, issuerHash, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (XMEMCMP(issuerHash, decoded.issuerHash, SHA_DIGEST_SIZE) == 0) {
|
||||
recipFound = 1;
|
||||
}
|
||||
|
||||
if (GetInt(&serialNum, pkiMsg, &idx, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (encOID != RSAk)
|
||||
return ALGO_ID_E;
|
||||
|
||||
/* read encryptedKey */
|
||||
if (pkiMsg[idx++] != ASN_OCTET_STRING)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetLength(pkiMsg, &idx, &encryptedKeySz, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (recipFound == 1)
|
||||
XMEMCPY(encryptedKey, &pkiMsg[idx], encryptedKeySz);
|
||||
idx += encryptedKeySz;
|
||||
|
||||
/* update good idx */
|
||||
savedIdx = idx;
|
||||
}
|
||||
|
||||
if (recipFound == 0) {
|
||||
CYASSL_MSG("No recipient found in envelopedData that matches input");
|
||||
return PKCS7_RECIP_E;
|
||||
}
|
||||
|
||||
/* remove EncryptedContentInfo */
|
||||
if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetAlgoId(pkiMsg, &idx, &encOID, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
/* read encryptedContent */
|
||||
if (pkiMsg[idx++] != ASN_OCTET_STRING)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
if (GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) < 0)
|
||||
return ASN_PARSE_E;
|
||||
|
||||
encryptedContent = XMALLOC(encryptedContentSz, NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz);
|
||||
|
||||
/* decrypt encryptedKey */
|
||||
keySz = RsaPrivateDecryptInline(encryptedKey, encryptedKeySz,
|
||||
&decryptedKey, &privKey);
|
||||
if (keySz < 0)
|
||||
return keySz;
|
||||
|
||||
/* decrypt encryptedContent, using NULL iv for now */
|
||||
XMEMSET(tmpIv, 0, sizeof(tmpIv));
|
||||
|
||||
if (encOID == DESb) {
|
||||
Des des;
|
||||
Des_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION);
|
||||
Des_CbcDecrypt(&des, encryptedContent, encryptedContent,
|
||||
encryptedContentSz);
|
||||
} else if (encOID == DES3b) {
|
||||
Des3 des;
|
||||
Des3_SetKey(&des, decryptedKey, tmpIv, DES_DECRYPTION);
|
||||
Des3_CbcDecrypt(&des, encryptedContent, encryptedContent,
|
||||
encryptedContentSz);
|
||||
} else {
|
||||
CYASSL_MSG("Unsupported content encryption OID type");
|
||||
return ALGO_ID_E;
|
||||
}
|
||||
|
||||
padLen = encryptedContent[encryptedContentSz-1];
|
||||
|
||||
/* copy plaintext to output */
|
||||
XMEMCPY(output, encryptedContent, encryptedContentSz - padLen);
|
||||
|
||||
/* free memory, zero out keys */
|
||||
XMEMSET(encryptedKey, 0, MAX_ENCRYPTED_KEY_SZ);
|
||||
XMEMSET(encryptedContent, 0, encryptedContentSz);
|
||||
XFREE(encryptedContent, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
return encryptedContentSz - padLen;
|
||||
}
|
||||
|
||||
|
||||
#else /* HAVE_PKCS7 */
|
||||
|
||||
|
@ -4027,106 +4027,193 @@ int compress_test(void)
|
||||
int pkcs7_test(void)
|
||||
{
|
||||
int ret = 0;
|
||||
byte* cert;
|
||||
byte out[2048];
|
||||
char data[] = "Hello World";
|
||||
word32 dataSz, outSz;
|
||||
PKCS7 msg;
|
||||
RNG rng;
|
||||
|
||||
word32 certSz;
|
||||
FILE* file;
|
||||
FILE* pkcs7File;
|
||||
|
||||
byte transIdOid[] =
|
||||
{ 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01,
|
||||
0x09, 0x07 };
|
||||
byte messageTypeOid[] =
|
||||
{ 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01,
|
||||
0x09, 0x02 };
|
||||
byte senderNonceOid[] =
|
||||
{ 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01,
|
||||
0x09, 0x05 };
|
||||
byte pkiStatusOid[] =
|
||||
{ 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01,
|
||||
0x09, 0x03 };
|
||||
byte transId[(SHA_DIGEST_SIZE + 1) * 2 + 1];
|
||||
byte messageType[] = { 0x13, 2, '1', '9' };
|
||||
byte senderNonce[34];
|
||||
byte pkiStatus[] = { 0x13, 1, '0' };
|
||||
|
||||
PKCS7Attrib attribs[] =
|
||||
/* Test the PKCS7 Signed-Data */
|
||||
{
|
||||
{ transIdOid, sizeof(transIdOid),
|
||||
transId, sizeof(transId) - 1 }, /* take off the null */
|
||||
{ messageTypeOid, sizeof(messageTypeOid),
|
||||
messageType, sizeof(messageType) },
|
||||
{ senderNonceOid, sizeof(senderNonceOid),
|
||||
senderNonce, sizeof(senderNonce) },
|
||||
{ pkiStatusOid, sizeof(pkiStatusOid),
|
||||
pkiStatus, sizeof(pkiStatus) }
|
||||
};
|
||||
byte* cert;
|
||||
byte out[2048];
|
||||
char data[] = "Hello World";
|
||||
word32 dataSz, outSz;
|
||||
PKCS7 msg;
|
||||
RNG rng;
|
||||
|
||||
dataSz = (word32) strlen(data);
|
||||
outSz = sizeof(out);
|
||||
word32 certSz;
|
||||
FILE* file;
|
||||
FILE* pkcs7File;
|
||||
|
||||
cert = (byte*)malloc(FOURK_BUF);
|
||||
if (cert == NULL)
|
||||
return -40;
|
||||
byte transIdOid[] =
|
||||
{ 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01,
|
||||
0x09, 0x07 };
|
||||
byte messageTypeOid[] =
|
||||
{ 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01,
|
||||
0x09, 0x02 };
|
||||
byte senderNonceOid[] =
|
||||
{ 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01,
|
||||
0x09, 0x05 };
|
||||
byte pkiStatusOid[] =
|
||||
{ 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xF8, 0x45, 0x01,
|
||||
0x09, 0x03 };
|
||||
byte transId[(SHA_DIGEST_SIZE + 1) * 2 + 1];
|
||||
byte messageType[] = { 0x13, 2, '1', '9' };
|
||||
byte senderNonce[34];
|
||||
byte pkiStatus[] = { 0x13, 1, '0' };
|
||||
|
||||
/* read in DER cert of recipient, into cert of size certSz */
|
||||
file = fopen(clientCert, "rb");
|
||||
PKCS7Attrib attribs[] =
|
||||
{
|
||||
{ transIdOid, sizeof(transIdOid),
|
||||
transId, sizeof(transId) - 1 }, /* take off the null */
|
||||
{ messageTypeOid, sizeof(messageTypeOid),
|
||||
messageType, sizeof(messageType) },
|
||||
{ senderNonceOid, sizeof(senderNonceOid),
|
||||
senderNonce, sizeof(senderNonce) },
|
||||
{ pkiStatusOid, sizeof(pkiStatusOid),
|
||||
pkiStatus, sizeof(pkiStatus) }
|
||||
};
|
||||
|
||||
if (!file)
|
||||
err_sys("can't open ./certs/client-cert.der, "
|
||||
"Please run from CyaSSL home dir", -40);
|
||||
dataSz = (word32) strlen(data);
|
||||
outSz = sizeof(out);
|
||||
|
||||
certSz = (word32)fread(cert, 1, FOURK_BUF, file);
|
||||
fclose(file);
|
||||
cert = (byte*)malloc(FOURK_BUF);
|
||||
if (cert == NULL)
|
||||
return -40;
|
||||
|
||||
ret = InitRng(&rng);
|
||||
senderNonce[0] = 0x04;
|
||||
senderNonce[1] = 0x20;
|
||||
RNG_GenerateBlock(&rng, &senderNonce[2], 32);
|
||||
/* read in DER cert of recipient, into cert of size certSz */
|
||||
file = fopen(clientCert, "rb");
|
||||
|
||||
PKCS7_InitWithCert(&msg, cert, certSz);
|
||||
msg.content = (byte*)data;
|
||||
msg.contentSz = dataSz;
|
||||
msg.hashOID = SHAh;
|
||||
msg.encryptOID = RSAk;
|
||||
msg.signedAttribs = attribs;
|
||||
msg.signedAttribsSz = sizeof(attribs)/sizeof(PKCS7Attrib);
|
||||
msg.rng = &rng;
|
||||
{
|
||||
Sha sha;
|
||||
byte digest[SHA_DIGEST_SIZE];
|
||||
int i,j;
|
||||
if (!file)
|
||||
err_sys("can't open ./certs/client-cert.der, "
|
||||
"Please run from CyaSSL home dir", -40);
|
||||
|
||||
transId[0] = 0x13;
|
||||
transId[1] = SHA_DIGEST_SIZE * 2;
|
||||
certSz = (word32)fread(cert, 1, FOURK_BUF, file);
|
||||
fclose(file);
|
||||
|
||||
InitSha(&sha);
|
||||
ShaUpdate(&sha, msg.publicKey, msg.publicKeySz);
|
||||
ShaFinal(&sha, digest);
|
||||
ret = InitRng(&rng);
|
||||
senderNonce[0] = 0x04;
|
||||
senderNonce[1] = 0x20;
|
||||
RNG_GenerateBlock(&rng, &senderNonce[2], 32);
|
||||
|
||||
for (i = 0, j = 2; i < SHA_DIGEST_SIZE; i++, j += 2) {
|
||||
snprintf((char*)&transId[j], 3, "%02x", digest[i]);
|
||||
PKCS7_InitWithCert(&msg, cert, certSz);
|
||||
msg.content = (byte*)data;
|
||||
msg.contentSz = dataSz;
|
||||
msg.hashOID = SHAh;
|
||||
msg.encryptOID = RSAk;
|
||||
msg.signedAttribs = attribs;
|
||||
msg.signedAttribsSz = sizeof(attribs)/sizeof(PKCS7Attrib);
|
||||
msg.rng = &rng;
|
||||
{
|
||||
Sha sha;
|
||||
byte digest[SHA_DIGEST_SIZE];
|
||||
int i,j;
|
||||
|
||||
transId[0] = 0x13;
|
||||
transId[1] = SHA_DIGEST_SIZE * 2;
|
||||
|
||||
InitSha(&sha);
|
||||
ShaUpdate(&sha, msg.publicKey, msg.publicKeySz);
|
||||
ShaFinal(&sha, digest);
|
||||
|
||||
for (i = 0, j = 2; i < SHA_DIGEST_SIZE; i++, j += 2) {
|
||||
snprintf((char*)&transId[j], 3, "%02x", digest[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = PKCS7_EncodeSignedData(&msg, out, outSz);
|
||||
if (ret < 0) {
|
||||
printf("Pkcs7_encrypt failed\n");
|
||||
return -42;
|
||||
}
|
||||
else
|
||||
outSz = ret;
|
||||
ret = PKCS7_EncodeSignedData(&msg, out, outSz);
|
||||
if (ret < 0) {
|
||||
printf("Pkcs7_encrypt failed\n");
|
||||
return -42;
|
||||
}
|
||||
else
|
||||
outSz = ret;
|
||||
|
||||
/* write PKCS#7 to output file for more testing */
|
||||
pkcs7File = fopen("./pkcs7test.der", "wb");
|
||||
if (!pkcs7File)
|
||||
return -43;
|
||||
ret = (int)fwrite(out, outSz, 1, pkcs7File);
|
||||
fclose(pkcs7File);
|
||||
/* write PKCS#7 to output file for more testing */
|
||||
pkcs7File = fopen("./pkcs7test.der", "wb");
|
||||
if (!pkcs7File)
|
||||
return -43;
|
||||
ret = (int)fwrite(out, outSz, 1, pkcs7File);
|
||||
fclose(pkcs7File);
|
||||
}
|
||||
/* Test the PKCS7 Enveloped-Data */
|
||||
{
|
||||
int cipher = DES3b;
|
||||
int envelopedSz, decodedSz;
|
||||
PKCS7 pkcs7;
|
||||
byte* cert;
|
||||
byte* privKey;
|
||||
byte enveloped[2048];
|
||||
byte decoded[2048];
|
||||
|
||||
size_t certSz;
|
||||
size_t privKeySz;
|
||||
FILE* certFile;
|
||||
FILE* keyFile;
|
||||
FILE* pkcs7File;
|
||||
const char* pkcs7OutFile = "pkcs7envelopedData.der";
|
||||
|
||||
const byte data[] = { /* Hello World */
|
||||
0x48,0x65,0x6c,0x6c,0x6f,0x20,0x57,0x6f,
|
||||
0x72,0x6c,0x64
|
||||
};
|
||||
|
||||
/* read client cert and key in DER format */
|
||||
cert = (byte*)malloc(FOURK_BUF);
|
||||
if (cert == NULL)
|
||||
return -201;
|
||||
|
||||
privKey = (byte*)malloc(FOURK_BUF);
|
||||
if (privKey == NULL)
|
||||
return -202;
|
||||
|
||||
certFile = fopen(clientCert, "rb");
|
||||
if (!certFile)
|
||||
err_sys("can't open ./certs/client-cert.der, "
|
||||
"Please run from CyaSSL home dir", -42);
|
||||
|
||||
certSz = fread(cert, 1, FOURK_BUF, certFile);
|
||||
fclose(certFile);
|
||||
|
||||
keyFile = fopen(clientKey, "rb");
|
||||
if (!keyFile)
|
||||
err_sys("can't open ./certs/client-key.der, "
|
||||
"Please run from CyaSSL home dir", -43);
|
||||
|
||||
privKeySz = fread(privKey, 1, FOURK_BUF, keyFile);
|
||||
fclose(keyFile);
|
||||
|
||||
PKCS7_InitWithCert(&pkcs7, cert, (word32)certSz);
|
||||
pkcs7.content = (byte*)data;
|
||||
pkcs7.contentSz = (word32)sizeof(data);
|
||||
pkcs7.contentOID = DATA;
|
||||
pkcs7.encryptOID = cipher;
|
||||
pkcs7.privateKey = privKey;
|
||||
pkcs7.privKeySize = (word32)privKeySz;
|
||||
|
||||
/* encode envelopedData */
|
||||
envelopedSz = PKCS7_EncodeEnvelopeData(&pkcs7, enveloped,
|
||||
sizeof(enveloped));
|
||||
if (envelopedSz <= 0)
|
||||
return -203;
|
||||
|
||||
/* decode envelopedData */
|
||||
decodedSz = PKCS7_DecodeEnvelopedData(&pkcs7, enveloped, envelopedSz,
|
||||
decoded, sizeof(decoded));
|
||||
if (decodedSz <= 0)
|
||||
return -204;
|
||||
|
||||
/* test decode result */
|
||||
if (memcmp(decoded, data, sizeof(data)) != 0) {
|
||||
return -205;
|
||||
}
|
||||
|
||||
/* output pkcs7 envelopedData for external testing */
|
||||
pkcs7File = fopen(pkcs7OutFile, "wb");
|
||||
if (!pkcs7File)
|
||||
return -206;
|
||||
|
||||
ret = (int)fwrite(enveloped, envelopedSz, 1, pkcs7File);
|
||||
fclose(pkcs7File);
|
||||
|
||||
free(cert);
|
||||
free(privKey);
|
||||
}
|
||||
|
||||
if (ret > 0)
|
||||
return 0;
|
||||
|
@ -446,6 +446,16 @@ CYASSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType);
|
||||
/* ASN.1 helper functions */
|
||||
CYASSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
|
||||
word32 maxIdx);
|
||||
CYASSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
|
||||
word32 maxIdx);
|
||||
CYASSL_LOCAL int GetSet(const byte* input, word32* inOutIdx, int* len,
|
||||
word32 maxIdx);
|
||||
CYASSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx,
|
||||
int* version);
|
||||
CYASSL_LOCAL int GetInt(mp_int* mpi, const byte* input, word32* inOutIdx,
|
||||
word32 maxIdx);
|
||||
CYASSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
|
||||
word32 maxIdx);
|
||||
CYASSL_LOCAL word32 SetLength(word32 length, byte* output);
|
||||
CYASSL_LOCAL word32 SetSequence(word32 len, byte* output);
|
||||
CYASSL_LOCAL word32 SetOctetString(word32 len, byte* output);
|
||||
@ -454,6 +464,8 @@ CYASSL_LOCAL word32 SetSet(word32 len, byte* output);
|
||||
CYASSL_LOCAL word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz);
|
||||
CYASSL_LOCAL int SetMyVersion(word32 version, byte* output, int header);
|
||||
CYASSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output);
|
||||
CYASSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
|
||||
int maxIdx);
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
/* ASN sig helpers */
|
||||
|
@ -119,6 +119,9 @@ enum {
|
||||
|
||||
REQ_ATTRIBUTE_E = -194, /* setting cert request attributes error */
|
||||
|
||||
PKCS7_OID_E = -195, /* PKCS#7, mismatched OID error */
|
||||
PKCS7_RECIP_E = -196, /* PKCS#7, recipient error */
|
||||
|
||||
MIN_CODE_E = -200 /* errors -101 - -199 */
|
||||
};
|
||||
|
||||
|
@ -63,19 +63,21 @@ typedef struct PKCS7Attrib {
|
||||
|
||||
|
||||
typedef struct PKCS7 {
|
||||
byte* content;
|
||||
word32 contentSz;
|
||||
int contentOID;
|
||||
byte* content; /* inner content, not owner */
|
||||
word32 contentSz; /* content size */
|
||||
int contentOID; /* PKCS#7 content type OID sum */
|
||||
|
||||
RNG* rng;
|
||||
|
||||
int hashOID;
|
||||
int encryptOID;
|
||||
int encryptOID; /* key encryption algorithm OID */
|
||||
|
||||
byte* singleCert;
|
||||
word32 singleCertSz;
|
||||
byte* issuer;
|
||||
byte* singleCert; /* recipient cert, DER, not owner */
|
||||
word32 singleCertSz; /* size of recipient cert buffer, bytes */
|
||||
byte* issuer;
|
||||
word32 issuerSz;
|
||||
byte* privateKey; /* recipient private key, DER, not owner */
|
||||
word32 privKeySize; /* size of private key buffer, bytes */
|
||||
byte issuerSn[MAX_SN_SZ];
|
||||
word32 issuerSnSz;
|
||||
byte publicKey[512];
|
||||
@ -87,6 +89,8 @@ typedef struct PKCS7 {
|
||||
|
||||
|
||||
CYASSL_LOCAL int SetContentType(int pkcs7TypeOID, byte* output);
|
||||
CYASSL_LOCAL int GetContentType(const byte* input, word32* inOutIdx,
|
||||
word32* oid, word32 maxIdx);
|
||||
CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz,
|
||||
int keyEncAlgo, int blockKeySz,
|
||||
RNG* rng, byte* contentKeyPlain,
|
||||
@ -99,6 +103,9 @@ CYASSL_API int PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
||||
byte* output, word32 outputSz);
|
||||
CYASSL_API int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7,
|
||||
byte* output, word32 outputSz);
|
||||
CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
||||
word32 pkiMsgSz, byte* output,
|
||||
word32 outputSz);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
@ -973,6 +973,8 @@ CYASSL_API int CyaSSL_GetObjectSize(void); /* object size based on build */
|
||||
CYASSL_API int CyaSSL_SetVersion(CYASSL* ssl, int version);
|
||||
CYASSL_API int CyaSSL_KeyPemToDer(const unsigned char*, int sz, unsigned char*,
|
||||
int, const char*);
|
||||
CYASSL_API int CyaSSL_CertPemToDer(const unsigned char*, int sz, unsigned char*,
|
||||
int, int);
|
||||
|
||||
typedef void (*CallbackCACache)(unsigned char* der, int sz, int type);
|
||||
typedef void (*CbMissingCRL)(const char* url);
|
||||
|
54
src/ssl.c
54
src/ssl.c
@ -1059,6 +1059,54 @@ int CyaSSL_CertManagerUnloadCAs(CYASSL_CERT_MANAGER* cm)
|
||||
}
|
||||
|
||||
|
||||
/* Return bytes written to buff or < 0 for error */
|
||||
int CyaSSL_CertPemToDer(const unsigned char* pem, int pemSz,
|
||||
unsigned char* buff, int buffSz,
|
||||
int type)
|
||||
{
|
||||
EncryptedInfo info;
|
||||
int eccKey = 0;
|
||||
int ret;
|
||||
buffer der;
|
||||
|
||||
CYASSL_ENTER("CyaSSL_CertPemToDer");
|
||||
|
||||
if (pem == NULL || buff == NULL || buffSz <= 0) {
|
||||
CYASSL_MSG("Bad pem der args");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (type != CERT_TYPE && type != CA_TYPE && type != CERTREQ_TYPE) {
|
||||
CYASSL_MSG("Bad cert type");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
info.set = 0;
|
||||
info.ctx = NULL;
|
||||
info.consumed = 0;
|
||||
der.buffer = NULL;
|
||||
|
||||
ret = PemToDer(pem, pemSz, type, &der, NULL, &info, &eccKey);
|
||||
if (ret < 0) {
|
||||
CYASSL_MSG("Bad Pem To Der");
|
||||
}
|
||||
else {
|
||||
if (der.length <= (word32)buffSz) {
|
||||
XMEMCPY(buff, der.buffer, der.length);
|
||||
ret = der.length;
|
||||
}
|
||||
else {
|
||||
CYASSL_MSG("Bad der length");
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
XFREE(der.buffer, NULL, DYNAMIC_TYPE_KEY);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* our KeyPemToDer password callback, password in userData */
|
||||
static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata)
|
||||
{
|
||||
@ -1582,6 +1630,12 @@ int CyaSSL_Init(void)
|
||||
XSTRNCPY(footer, "-----END CERTIFICATE-----", sizeof(footer));
|
||||
dynamicType = (type == CA_TYPE) ? DYNAMIC_TYPE_CA :
|
||||
DYNAMIC_TYPE_CERT;
|
||||
} else if (type == CERTREQ_TYPE) {
|
||||
XSTRNCPY(header, "-----BEGIN CERTIFICATE REQUEST-----",
|
||||
sizeof(header));
|
||||
XSTRNCPY(footer, "-----END CERTIFICATE REQUEST-----",
|
||||
sizeof(footer));
|
||||
dynamicType = DYNAMIC_TYPE_KEY;
|
||||
} else if (type == DH_PARAM_TYPE) {
|
||||
XSTRNCPY(header, "-----BEGIN DH PARAMETERS-----", sizeof(header));
|
||||
XSTRNCPY(footer, "-----END DH PARAMETERS-----", sizeof(footer));
|
||||
|
@ -974,7 +974,7 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
|
||||
|
||||
if (sniType != type) {
|
||||
offset += sniLen;
|
||||
listLen -= MIN(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen);
|
||||
listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -985,7 +985,7 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
|
||||
}
|
||||
}
|
||||
|
||||
len16 -= MIN(2 * OPAQUE16_LEN + extLen, len16);
|
||||
len16 -= min(2 * OPAQUE16_LEN + extLen, len16);
|
||||
}
|
||||
|
||||
return len16 ? BUFFER_ERROR : SSL_SUCCESS;
|
||||
|
@ -440,6 +440,8 @@ void test_CyaSSL_UseSNI(void)
|
||||
CyaSSL_free(ssl);
|
||||
CyaSSL_CTX_free(ctx);
|
||||
|
||||
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
|
||||
|
||||
/* Testing success case at ctx */
|
||||
client_callbacks.ctx_ready = server_callbacks.ctx_ready = use_SNI_at_ctx;
|
||||
server_callbacks.on_result = verify_SNI_real_matching;
|
||||
@ -473,6 +475,8 @@ void test_CyaSSL_UseSNI(void)
|
||||
|
||||
test_CyaSSL_client_server(&client_callbacks, &server_callbacks);
|
||||
|
||||
#endif
|
||||
|
||||
test_CyaSSL_SNI_GetFromBuffer();
|
||||
}
|
||||
#endif /* HAVE_SNI */
|
||||
|
Loading…
Reference in New Issue
Block a user