forked from wolfSSL/wolfssl
Merge branch 'master' of github.com:cyassl/cyassl
Conflicts: ctaocrypt/test/test.c cyassl/ctaocrypt/pkcs7.h
This commit is contained in:
@@ -439,7 +439,7 @@ CYASSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int GetSequence(const byte* input, word32* inOutIdx, int* len,
|
CYASSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,
|
||||||
word32 maxIdx)
|
word32 maxIdx)
|
||||||
{
|
{
|
||||||
int length = -1;
|
int length = -1;
|
||||||
@@ -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;
|
int length = -1;
|
||||||
word32 idx = *inOutIdx;
|
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 */
|
/* 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;
|
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 maxIdx)
|
||||||
{
|
{
|
||||||
word32 i = *inOutIdx;
|
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)
|
word32 maxIdx)
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
@@ -6064,39 +6065,9 @@ int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
|
|||||||
#endif
|
#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 */
|
/* 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;
|
Sha sha;
|
||||||
int length; /* length of all distinguished names */
|
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 */
|
/* Get Revoked Cert list, 0 on success */
|
||||||
static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
|
static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
|
||||||
int maxIdx)
|
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 */
|
/* internal worker, handles both escaped and normal line endings */
|
||||||
static int DoBase64_Encode(const byte* in, word32 inLen, byte* out,
|
static int DoBase64_Encode(const byte* in, word32 inLen, byte* out,
|
||||||
word32* outLen, int escaped)
|
word32* outLen, int escaped)
|
||||||
{
|
{
|
||||||
|
int ret = 0;
|
||||||
word32 i = 0,
|
word32 i = 0,
|
||||||
j = 0,
|
j = 0,
|
||||||
n = 0; /* new line counter */
|
n = 0; /* new line counter */
|
||||||
@@ -163,6 +240,8 @@ static int DoBase64_Encode(const byte* in, word32 inLen, byte* out,
|
|||||||
|
|
||||||
outSz += addSz;
|
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;
|
if (outSz > *outLen) return BAD_FUNC_ARG;
|
||||||
|
|
||||||
while (inLen > 2) {
|
while (inLen > 2) {
|
||||||
@@ -177,26 +256,25 @@ static int DoBase64_Encode(const byte* in, word32 inLen, byte* out,
|
|||||||
byte e4 = b3 & 0x3F;
|
byte e4 = b3 & 0x3F;
|
||||||
|
|
||||||
/* store */
|
/* store */
|
||||||
out[i++] = base64Encode[e1];
|
ret = Escape(escaped, e1, out, &i, *outLen, 0);
|
||||||
out[i++] = base64Encode[e2];
|
if (ret != 0) break;
|
||||||
out[i++] = base64Encode[e3];
|
ret = Escape(escaped, e2, out, &i, *outLen, 0);
|
||||||
out[i++] = base64Encode[e4];
|
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;
|
inLen -= 3;
|
||||||
|
|
||||||
if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen) {
|
if ((++n % (PEM_LINE_SZ / 4)) == 0 && inLen) {
|
||||||
if (escaped) {
|
ret = Escape(escaped, '\n', out, &i, *outLen, 1);
|
||||||
out[i++] = '%';
|
if (ret != 0) break;
|
||||||
out[i++] = '0';
|
|
||||||
out[i++] = 'A';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
out[i++] = '\n';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* last integral */
|
/* last integral */
|
||||||
if (inLen) {
|
if (inLen && ret == 0) {
|
||||||
int twoBytes = (inLen == 2);
|
int twoBytes = (inLen == 2);
|
||||||
|
|
||||||
byte b1 = in[j++];
|
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 e2 = ((b1 & 0x3) << 4) | (b2 >> 4);
|
||||||
byte e3 = (b2 & 0xF) << 2;
|
byte e3 = (b2 & 0xF) << 2;
|
||||||
|
|
||||||
out[i++] = base64Encode[e1];
|
ret = Escape(escaped, e1, out, &i, *outLen, 0);
|
||||||
out[i++] = base64Encode[e2];
|
if (ret == 0)
|
||||||
out[i++] = (twoBytes) ? base64Encode[e3] : PAD;
|
ret = Escape(escaped, e2, out, &i, *outLen, 0);
|
||||||
out[i++] = PAD;
|
if (ret == 0) {
|
||||||
}
|
/* third */
|
||||||
|
if (twoBytes)
|
||||||
if (escaped) {
|
ret = Escape(escaped, e3, out, &i, *outLen, 0);
|
||||||
out[i++] = '%';
|
|
||||||
out[i++] = '0';
|
|
||||||
out[i++] = 'A';
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
out[i++] = '\n';
|
ret = Escape(escaped, '=', out, &i, *outLen, 1);
|
||||||
if (i != outSz)
|
}
|
||||||
return ASN_INPUT_E;
|
/* fourth always pad */
|
||||||
*outLen = outSz;
|
if (ret == 0)
|
||||||
|
ret = Escape(escaped, '=', out, &i, *outLen, 1);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
if (ret == 0)
|
||||||
|
ret = Escape(escaped, '\n', out, &i, *outLen, 1);
|
||||||
|
|
||||||
|
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);
|
XSTRNCPY(buffer, "Setting cert request attributes error", max);
|
||||||
break;
|
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:
|
default:
|
||||||
XSTRNCPY(buffer, "unknown error number", max);
|
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)
|
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;
|
return ALGO_ID_E;
|
||||||
|
|
||||||
keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, keyType, 0);
|
keyEncAlgSz = SetAlgoID(keyEncAlgo, keyAlgArray, keyType, 0);
|
||||||
|
if (keyEncAlgSz == 0)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
/* EncryptedKey */
|
/* EncryptedKey */
|
||||||
InitRsaKey(&pubKey, 0);
|
InitRsaKey(&pubKey, 0);
|
||||||
@@ -642,6 +671,13 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
byte contentEncAlgo[MAX_ALGO_SZ];
|
byte contentEncAlgo[MAX_ALGO_SZ];
|
||||||
byte encContentOctet[MAX_OCTET_STR_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) {
|
switch (pkcs7->encryptOID) {
|
||||||
case DESb:
|
case DESb:
|
||||||
blockKeySz = DES_KEYLEN;
|
blockKeySz = DES_KEYLEN;
|
||||||
@@ -662,7 +698,7 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
/* version */
|
/* version */
|
||||||
verSz = SetMyVersion(0, ver, 0);
|
verSz = SetMyVersion(0, ver, 0);
|
||||||
|
|
||||||
/* generate random content enc key */
|
/* generate random content encryption key */
|
||||||
InitRng(&rng);
|
InitRng(&rng);
|
||||||
RNG_GenerateBlock(&rng, contentKeyPlain, blockKeySz);
|
RNG_GenerateBlock(&rng, contentKeyPlain, blockKeySz);
|
||||||
|
|
||||||
@@ -680,8 +716,13 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
|
|
||||||
/* EncryptedContentInfo */
|
/* EncryptedContentInfo */
|
||||||
contentTypeSz = SetContentType(pkcs7->contentOID, contentType);
|
contentTypeSz = SetContentType(pkcs7->contentOID, contentType);
|
||||||
|
if (contentTypeSz == 0)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
|
contentEncAlgoSz = SetAlgoID(pkcs7->encryptOID, contentEncAlgo,
|
||||||
blkType, 0);
|
blkType, 0);
|
||||||
|
if (contentEncAlgoSz == 0)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
/* allocate memory for encrypted content, pad if necessary */
|
/* allocate memory for encrypted content, pad if necessary */
|
||||||
padSz = DES_BLOCK_SIZE - (pkcs7->contentSz % DES_BLOCK_SIZE);
|
padSz = DES_BLOCK_SIZE - (pkcs7->contentSz % DES_BLOCK_SIZE);
|
||||||
@@ -696,7 +737,7 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
dynamicFlag = 1;
|
dynamicFlag = 1;
|
||||||
|
|
||||||
for (i = 0; i < padSz; i++) {
|
for (i = 0; i < padSz; i++) {
|
||||||
plain[pkcs7->contentSz + i + 1] = padSz;
|
plain[pkcs7->contentSz + i] = padSz;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -711,16 +752,17 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
return MEMORY_E;
|
return MEMORY_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* use NULL iv for now */
|
||||||
byte tmpIv[blockKeySz];
|
byte tmpIv[blockKeySz];
|
||||||
|
XMEMSET(tmpIv, 0, sizeof(tmpIv));
|
||||||
|
|
||||||
if (pkcs7->encryptOID == DESb) {
|
if (pkcs7->encryptOID == DESb) {
|
||||||
Des des;
|
Des des;
|
||||||
RNG_GenerateBlock(&rng, tmpIv, (word32)sizeof(tmpIv));
|
|
||||||
Des_SetKey(&des, contentKeyPlain, tmpIv, DES_ENCRYPTION);
|
Des_SetKey(&des, contentKeyPlain, tmpIv, DES_ENCRYPTION);
|
||||||
Des_CbcEncrypt(&des, encryptedContent, plain, desOutSz);
|
Des_CbcEncrypt(&des, encryptedContent, plain, desOutSz);
|
||||||
|
|
||||||
} else if (pkcs7->encryptOID == DES3b) {
|
} else if (pkcs7->encryptOID == DES3b) {
|
||||||
Des3 des3;
|
Des3 des3;
|
||||||
RNG_GenerateBlock(&rng, tmpIv, (word32)sizeof(tmpIv));
|
|
||||||
Des3_SetKey(&des3, contentKeyPlain, tmpIv, DES_ENCRYPTION);
|
Des3_SetKey(&des3, contentKeyPlain, tmpIv, DES_ENCRYPTION);
|
||||||
Des3_CbcEncrypt(&des3, encryptedContent, plain, desOutSz);
|
Des3_CbcEncrypt(&des3, encryptedContent, plain, desOutSz);
|
||||||
}
|
}
|
||||||
@@ -784,6 +826,10 @@ int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7, byte* output, word32 outputSz)
|
|||||||
#ifdef NO_RC4
|
#ifdef NO_RC4
|
||||||
FreeRng(&rng);
|
FreeRng(&rng);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
XMEMSET(contentKeyPlain, 0, MAX_CONTENT_KEY_LEN);
|
||||||
|
XMEMSET(contentKeyEnc, 0, MAX_ENCRYPTED_KEY_SZ);
|
||||||
|
|
||||||
if (dynamicFlag)
|
if (dynamicFlag)
|
||||||
XFREE(plain, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
|
XFREE(plain, NULL, DYNAMMIC_TYPE_TMP_BUFFER);
|
||||||
XFREE(encryptedContent, NULL, DYNAMIC_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;
|
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 */
|
#else /* HAVE_PKCS7 */
|
||||||
|
|
||||||
|
@@ -4027,6 +4027,9 @@ int compress_test(void)
|
|||||||
int pkcs7_test(void)
|
int pkcs7_test(void)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
/* Test the PKCS7 Signed-Data */
|
||||||
|
{
|
||||||
byte* cert;
|
byte* cert;
|
||||||
byte out[2048];
|
byte out[2048];
|
||||||
char data[] = "Hello World";
|
char data[] = "Hello World";
|
||||||
@@ -4127,6 +4130,90 @@ int pkcs7_test(void)
|
|||||||
return -43;
|
return -43;
|
||||||
ret = (int)fwrite(out, outSz, 1, pkcs7File);
|
ret = (int)fwrite(out, outSz, 1, pkcs7File);
|
||||||
fclose(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)
|
if (ret > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -446,6 +446,16 @@ CYASSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType);
|
|||||||
/* ASN.1 helper functions */
|
/* ASN.1 helper functions */
|
||||||
CYASSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
|
CYASSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
|
||||||
word32 maxIdx);
|
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 SetLength(word32 length, byte* output);
|
||||||
CYASSL_LOCAL word32 SetSequence(word32 len, byte* output);
|
CYASSL_LOCAL word32 SetSequence(word32 len, byte* output);
|
||||||
CYASSL_LOCAL word32 SetOctetString(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 word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz);
|
||||||
CYASSL_LOCAL int SetMyVersion(word32 version, byte* output, int header);
|
CYASSL_LOCAL int SetMyVersion(word32 version, byte* output, int header);
|
||||||
CYASSL_LOCAL int SetSerialNumber(const byte* sn, word32 snSz, byte* output);
|
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
|
#ifdef HAVE_ECC
|
||||||
/* ASN sig helpers */
|
/* ASN sig helpers */
|
||||||
|
@@ -119,6 +119,9 @@ enum {
|
|||||||
|
|
||||||
REQ_ATTRIBUTE_E = -194, /* setting cert request attributes error */
|
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 */
|
MIN_CODE_E = -200 /* errors -101 - -199 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -63,19 +63,21 @@ typedef struct PKCS7Attrib {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct PKCS7 {
|
typedef struct PKCS7 {
|
||||||
byte* content;
|
byte* content; /* inner content, not owner */
|
||||||
word32 contentSz;
|
word32 contentSz; /* content size */
|
||||||
int contentOID;
|
int contentOID; /* PKCS#7 content type OID sum */
|
||||||
|
|
||||||
RNG* rng;
|
RNG* rng;
|
||||||
|
|
||||||
int hashOID;
|
int hashOID;
|
||||||
int encryptOID;
|
int encryptOID; /* key encryption algorithm OID */
|
||||||
|
|
||||||
byte* singleCert;
|
byte* singleCert; /* recipient cert, DER, not owner */
|
||||||
word32 singleCertSz;
|
word32 singleCertSz; /* size of recipient cert buffer, bytes */
|
||||||
byte* issuer;
|
byte* issuer;
|
||||||
word32 issuerSz;
|
word32 issuerSz;
|
||||||
|
byte* privateKey; /* recipient private key, DER, not owner */
|
||||||
|
word32 privKeySize; /* size of private key buffer, bytes */
|
||||||
byte issuerSn[MAX_SN_SZ];
|
byte issuerSn[MAX_SN_SZ];
|
||||||
word32 issuerSnSz;
|
word32 issuerSnSz;
|
||||||
byte publicKey[512];
|
byte publicKey[512];
|
||||||
@@ -87,6 +89,8 @@ typedef struct PKCS7 {
|
|||||||
|
|
||||||
|
|
||||||
CYASSL_LOCAL int SetContentType(int pkcs7TypeOID, byte* output);
|
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,
|
CYASSL_LOCAL int CreateRecipientInfo(const byte* cert, word32 certSz,
|
||||||
int keyEncAlgo, int blockKeySz,
|
int keyEncAlgo, int blockKeySz,
|
||||||
RNG* rng, byte* contentKeyPlain,
|
RNG* rng, byte* contentKeyPlain,
|
||||||
@@ -99,6 +103,9 @@ CYASSL_API int PKCS7_EncodeSignedData(PKCS7* pkcs7,
|
|||||||
byte* output, word32 outputSz);
|
byte* output, word32 outputSz);
|
||||||
CYASSL_API int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7,
|
CYASSL_API int PKCS7_EncodeEnvelopeData(PKCS7* pkcs7,
|
||||||
byte* output, word32 outputSz);
|
byte* output, word32 outputSz);
|
||||||
|
CYASSL_API int PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* pkiMsg,
|
||||||
|
word32 pkiMsgSz, byte* output,
|
||||||
|
word32 outputSz);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* 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_SetVersion(CYASSL* ssl, int version);
|
||||||
CYASSL_API int CyaSSL_KeyPemToDer(const unsigned char*, int sz, unsigned char*,
|
CYASSL_API int CyaSSL_KeyPemToDer(const unsigned char*, int sz, unsigned char*,
|
||||||
int, const 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 (*CallbackCACache)(unsigned char* der, int sz, int type);
|
||||||
typedef void (*CbMissingCRL)(const char* url);
|
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 */
|
/* our KeyPemToDer password callback, password in userData */
|
||||||
static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* 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));
|
XSTRNCPY(footer, "-----END CERTIFICATE-----", sizeof(footer));
|
||||||
dynamicType = (type == CA_TYPE) ? DYNAMIC_TYPE_CA :
|
dynamicType = (type == CA_TYPE) ? DYNAMIC_TYPE_CA :
|
||||||
DYNAMIC_TYPE_CERT;
|
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) {
|
} else if (type == DH_PARAM_TYPE) {
|
||||||
XSTRNCPY(header, "-----BEGIN DH PARAMETERS-----", sizeof(header));
|
XSTRNCPY(header, "-----BEGIN DH PARAMETERS-----", sizeof(header));
|
||||||
XSTRNCPY(footer, "-----END DH PARAMETERS-----", sizeof(footer));
|
XSTRNCPY(footer, "-----END DH PARAMETERS-----", sizeof(footer));
|
||||||
|
@@ -974,7 +974,7 @@ int TLSX_SNI_GetFromBuffer(const byte* clientHello, word32 helloSz,
|
|||||||
|
|
||||||
if (sniType != type) {
|
if (sniType != type) {
|
||||||
offset += sniLen;
|
offset += sniLen;
|
||||||
listLen -= MIN(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen);
|
listLen -= min(ENUM_LEN + OPAQUE16_LEN + sniLen, listLen);
|
||||||
continue;
|
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;
|
return len16 ? BUFFER_ERROR : SSL_SUCCESS;
|
||||||
|
@@ -440,6 +440,8 @@ void test_CyaSSL_UseSNI(void)
|
|||||||
CyaSSL_free(ssl);
|
CyaSSL_free(ssl);
|
||||||
CyaSSL_CTX_free(ctx);
|
CyaSSL_CTX_free(ctx);
|
||||||
|
|
||||||
|
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
|
||||||
|
|
||||||
/* Testing success case at ctx */
|
/* Testing success case at ctx */
|
||||||
client_callbacks.ctx_ready = server_callbacks.ctx_ready = use_SNI_at_ctx;
|
client_callbacks.ctx_ready = server_callbacks.ctx_ready = use_SNI_at_ctx;
|
||||||
server_callbacks.on_result = verify_SNI_real_matching;
|
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);
|
test_CyaSSL_client_server(&client_callbacks, &server_callbacks);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
test_CyaSSL_SNI_GetFromBuffer();
|
test_CyaSSL_SNI_GetFromBuffer();
|
||||||
}
|
}
|
||||||
#endif /* HAVE_SNI */
|
#endif /* HAVE_SNI */
|
||||||
|
Reference in New Issue
Block a user