Merge pull request #2348 from cconlon/scepchanges

Changes to support SCEP Expansion
This commit is contained in:
toddouska
2019-07-16 15:26:15 -07:00
committed by GitHub
3 changed files with 177 additions and 13 deletions

View File

@@ -10073,6 +10073,12 @@ typedef struct DerCert {
#ifdef WOLFSSL_CERT_REQ
/* Write a set header to output */
static word32 SetPrintableString(word32 len, byte* output)
{
output[0] = ASN_PRINTABLE_STRING;
return SetLength(len, output + 1) + 1;
}
static word32 SetUTF8String(word32 len, byte* output)
{
output[0] = ASN_UTF8STRING;
@@ -11969,7 +11975,8 @@ int wc_MakeNtruCert(Cert* cert, byte* derBuffer, word32 derSz,
#ifdef WOLFSSL_CERT_REQ
static int SetReqAttrib(byte* output, char* pw, int extSz)
static int SetReqAttrib(byte* output, char* pw, int pwPrintableString,
int extSz)
{
static const byte cpOid[] =
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
@@ -11998,7 +12005,11 @@ static int SetReqAttrib(byte* output, char* pw, int extSz)
if (pw && pw[0]) {
pwSz = (int)XSTRLEN(pw);
cpStrSz = SetUTF8String(pwSz, cpStr);
if (pwPrintableString) {
cpStrSz = SetPrintableString(pwSz, cpStr);
} else {
cpStrSz = SetUTF8String(pwSz, cpStr);
}
cpSetSz = SetSet(cpStrSz + pwSz, cpSet);
cpSeqSz = SetSequence(sizeof(cpOid) + cpSetSz + cpStrSz + pwSz, cpSeq);
cpSz = cpSeqSz + sizeof(cpOid) + cpSetSz + cpStrSz + pwSz;
@@ -12206,8 +12217,9 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey,
#endif /* WOLFSSL_CERT_EXT */
}
der->attribSz = SetReqAttrib(der->attrib,
cert->challengePw, der->extensionsSz);
der->attribSz = SetReqAttrib(der->attrib, cert->challengePw,
cert->challengePwPrintableString,
der->extensionsSz);
if (der->attribSz <= 0)
return REQ_ATTRIBUTE_E;

View File

@@ -1379,12 +1379,99 @@ static int EncodeAttributes(EncodedAttrib* ea, int eaSz,
}
static int FlattenAttributes(byte* output, EncodedAttrib* ea, int eaSz)
{
int i, idx;
typedef struct FlatAttrib {
byte* data;
word32 dataSz;
} FlatAttrib;
/* Free FlatAttrib array and memory allocated to internal struct members */
static void FreeAttribArray(PKCS7* pkcs7, FlatAttrib** arr, int rows)
{
int i;
if (arr) {
for (i = 0; i < rows; i++) {
if (arr[i]) {
if (arr[i]->data) {
ForceZero(arr[i]->data, arr[i]->dataSz);
XFREE(arr[i]->data, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
ForceZero(arr[i], sizeof(FlatAttrib));
XFREE(arr[i], pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
}
ForceZero(arr, rows);
XFREE(arr, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
(void)pkcs7;
}
/* Sort FlatAttrib array in ascending order */
static int SortAttribArray(FlatAttrib** arr, int rows)
{
int i, j;
word32 minSz, minIdx;
FlatAttrib* a = NULL;
FlatAttrib* b = NULL;
FlatAttrib* tmp = NULL;
if (arr == NULL) {
return BAD_FUNC_ARG;
}
for (i = 0; i < rows; i++) {
a = arr[i];
minSz = a->dataSz;
minIdx = i;
for (j = i+1; j < rows; j++) {
b = arr[j];
if (b->dataSz < minSz) {
minSz = b->dataSz;
minIdx = j;
}
}
if (minSz < a->dataSz) {
/* swap array positions */
tmp = arr[i];
arr[i] = arr[minIdx];
arr[minIdx] = tmp;
}
}
return 0;
}
/* Build up array of FlatAttrib structs from EncodedAttrib ones. FlatAttrib
* holds flattened DER encoding of each attribute */
static int FlattenEncodedAttribs(PKCS7* pkcs7, FlatAttrib** derArr, int rows,
EncodedAttrib* ea, int eaSz)
{
int i, idx, sz;
byte* output = NULL;
FlatAttrib* fa = NULL;
if (pkcs7 == NULL || derArr == NULL || ea == NULL) {
WOLFSSL_MSG("Invalid arguments to FlattenEncodedAttribs");
return BAD_FUNC_ARG;
}
if (rows != eaSz) {
WOLFSSL_MSG("DER array not large enough to hold attribute count");
return BAD_FUNC_ARG;
}
idx = 0;
for (i = 0; i < eaSz; i++) {
sz = ea[i].valueSeqSz + ea[i].oidSz + ea[i].valueSetSz + ea[i].valueSz;
output = (byte*)XMALLOC(sz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (output == NULL) {
return MEMORY_E;
}
idx = 0;
XMEMCPY(output + idx, ea[i].valueSeq, ea[i].valueSeqSz);
idx += ea[i].valueSeqSz;
XMEMCPY(output + idx, ea[i].oid, ea[i].oidSz);
@@ -1392,8 +1479,70 @@ static int FlattenAttributes(byte* output, EncodedAttrib* ea, int eaSz)
XMEMCPY(output + idx, ea[i].valueSet, ea[i].valueSetSz);
idx += ea[i].valueSetSz;
XMEMCPY(output + idx, ea[i].value, ea[i].valueSz);
idx += ea[i].valueSz;
fa = derArr[i];
fa->data = output;
fa->dataSz = sz;
}
return 0;
}
/* Sort and Flatten EncodedAttrib attributes into output buffer */
static int FlattenAttributes(PKCS7* pkcs7, byte* output, EncodedAttrib* ea,
int eaSz)
{
int i, idx, ret;
FlatAttrib** derArr = NULL;
FlatAttrib* fa = NULL;
if (pkcs7 == NULL || output == NULL || ea == NULL) {
return BAD_FUNC_ARG;
}
/* create array of FlatAttrib struct pointers to hold DER attribs */
derArr = (FlatAttrib**) XMALLOC(eaSz * sizeof(FlatAttrib*), pkcs7->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (derArr == NULL) {
return MEMORY_E;
}
ForceZero(derArr, eaSz);
for (i = 0; i < eaSz; i++) {
derArr[i] = (FlatAttrib*) XMALLOC(sizeof(FlatAttrib), pkcs7->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (derArr[i] == NULL) {
FreeAttribArray(pkcs7, derArr, eaSz);
return MEMORY_E;
}
ForceZero(derArr[i], sizeof(FlatAttrib));
}
/* flatten EncodedAttrib into DER byte arrays */
ret = FlattenEncodedAttribs(pkcs7, derArr, eaSz, ea, eaSz);
if (ret != 0) {
FreeAttribArray(pkcs7, derArr, eaSz);
return ret;
}
/* SET OF DER signed attributes must be sorted in ascending order */
ret = SortAttribArray(derArr, eaSz);
if (ret != 0) {
FreeAttribArray(pkcs7, derArr, eaSz);
return ret;
}
/* copy sorted DER attribute arrays into output buffer */
idx = 0;
for (i = 0; i < eaSz; i++) {
fa = derArr[i];
XMEMCPY(output + idx, fa->data, fa->dataSz);
idx += fa->dataSz;
}
FreeAttribArray(pkcs7, derArr, eaSz);
return 0;
}
@@ -2086,7 +2235,7 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd,
return MEMORY_E;
}
FlattenAttributes(flatSignedAttribs,
FlattenAttributes(pkcs7, flatSignedAttribs,
esd->signedAttribs, esd->signedAttribsCount);
esd->signedAttribSetSz = SetImplicit(ASN_SET, 0, esd->signedAttribsSz,
esd->signedAttribSet);
@@ -10123,7 +10272,8 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output,
return MEMORY_E;
}
FlattenAttributes(flatAuthAttribs, authAttribs, authAttribsCount);
FlattenAttributes(pkcs7, flatAuthAttribs, authAttribs,
authAttribsCount);
authAttribsSetSz = SetImplicit(ASN_SET, 1, authAttribsSz,
authAttribSet);
@@ -10167,7 +10317,8 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output,
return MEMORY_E;
}
FlattenAttributes(flatUnauthAttribs, unauthAttribs, unauthAttribsCount);
FlattenAttributes(pkcs7, flatUnauthAttribs, unauthAttribs,
unauthAttribsCount);
unauthAttribsSetSz = SetImplicit(ASN_SET, 2, unauthAttribsSz,
unauthAttribSet);
}
@@ -11121,7 +11272,7 @@ int wc_PKCS7_EncodeEncryptedData(PKCS7* pkcs7, byte* output, word32 outputSz)
return MEMORY_E;
}
FlattenAttributes(flatAttribs, attribs, attribsCount);
FlattenAttributes(pkcs7, flatAttribs, attribs, attribsCount);
attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet);
} else {

View File

@@ -296,6 +296,7 @@ typedef struct Cert {
#endif
#ifdef WOLFSSL_CERT_REQ
char challengePw[CTC_NAME_SIZE];
int challengePwPrintableString; /* encode as PrintableString */
#endif
void* decodedCert; /* internal DecodedCert allocated from heap */
byte* der; /* Pointer to buffer of current DecodedCert cache */