add CMS signingTime attribute support for SignedData

This commit is contained in:
Chris Conlon
2018-08-23 11:30:57 -06:00
committed by David Garske
parent 56f1b68442
commit a25a637270
3 changed files with 125 additions and 5 deletions

View File

@@ -4861,6 +4861,92 @@ int GetTimeString(byte* date, int format, char* buf, int len)
#endif /* OPENSSL_ALL || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ #endif /* OPENSSL_ALL || WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
#if !defined(NO_ASN_TIME) && defined(HAVE_PKCS7)
/* set current time string, either UTC or GeneralizedTime */
int GetAsnTimeString(byte* buf, word32 len)
{
time_t currTime;
struct tm* ts = NULL;
struct tm* tmpTime = NULL;
#if defined(NEED_TMP_TIME)
struct tm tmpTimeStorage;
tmpTime = &tmpTimeStorage;
#else
(void)tmpTime;
#endif
byte* data_ptr = buf;
word32 data_len = 0;
int year, mon, day, hour, min, sec;
WOLFSSL_ENTER("SetAsnTimeString");
if (buf == NULL || len == 0)
return BAD_FUNC_ARG;
currTime = XTIME(0);
ts = (struct tm *)XGMTIME(&currTime, tmpTime);
if (ts == NULL){
WOLFSSL_MSG("failed to get time data.");
return ASN_TIME_E;
}
/* Note ASN_UTC_TIME_SIZE and ASN_GENERALIZED_TIME_SIZE include space for
* the null terminator. ASN encoded values leave off the terminator. */
if (ts->tm_year >= 50 && ts->tm_year < 150){
/* UTC Time */
char utc_str[ASN_UTC_TIME_SIZE];
data_len = ASN_UTC_TIME_SIZE -1 + 2;
if (len < data_len)
return BUFFER_E;
if (ts->tm_year >= 50 && ts->tm_year < 100){
year = ts->tm_year;
} else if (ts->tm_year >= 100 && ts->tm_year < 150){
year = ts->tm_year - 100;
}
mon = ts->tm_mon + 1;
day = ts->tm_mday;
hour = ts->tm_hour;
min = ts->tm_min;
sec = ts->tm_sec;
XSNPRINTF((char *)utc_str, ASN_UTC_TIME_SIZE,
"%02d%02d%02d%02d%02d%02dZ", year, mon, day, hour, min, sec);
*data_ptr = (byte) ASN_UTC_TIME; data_ptr++;
/* -1 below excludes null terminator */
*data_ptr = (byte) ASN_UTC_TIME_SIZE - 1; data_ptr++;
XMEMCPY(data_ptr,(byte *)utc_str, ASN_UTC_TIME_SIZE - 1);
} else {
/* GeneralizedTime */
char gt_str[ASN_GENERALIZED_TIME_SIZE];
data_len = ASN_GENERALIZED_TIME_SIZE + 1;
if (len < data_len)
return BUFFER_E;
year = ts->tm_year + 1900;
mon = ts->tm_mon + 1;
day = ts->tm_mday;
hour = ts->tm_hour;
min = ts->tm_min;
sec = ts->tm_sec;
XSNPRINTF((char *)gt_str, ASN_GENERALIZED_TIME_SIZE,
"%4d%02d%02d%02d%02d%02dZ", year, mon, day, hour, min, sec);
*data_ptr = (byte) ASN_GENERALIZED_TIME; data_ptr++;
/* -1 below excludes null terminator */
*data_ptr = (byte) ASN_GENERALIZED_TIME_SIZE - 1; data_ptr++;
XMEMCPY(data_ptr,(byte *)gt_str, ASN_GENERALIZED_TIME_SIZE - 1);
}
return data_len;
}
#endif /* !NO_ASN_TIME && HAVE_PKCS7 */
#if defined(USE_WOLF_VALIDDATE) #if defined(USE_WOLF_VALIDDATE)
/* to the second */ /* to the second */

View File

@@ -575,7 +575,7 @@ typedef struct ESD {
byte signerDigAlgoId[MAX_ALGO_SZ]; byte signerDigAlgoId[MAX_ALGO_SZ];
byte digEncAlgoId[MAX_ALGO_SZ]; byte digEncAlgoId[MAX_ALGO_SZ];
byte signedAttribSet[MAX_SET_SZ]; byte signedAttribSet[MAX_SET_SZ];
EncodedAttrib signedAttribs[6]; EncodedAttrib signedAttribs[7];
byte signerDigest[MAX_OCTET_STR_SZ]; byte signerDigest[MAX_OCTET_STR_SZ];
word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz; word32 innerOctetsSz, innerContSeqSz, contentInfoSeqSz;
word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz, word32 outerSeqSz, outerContentSz, innerSeqSz, versionSz, digAlgoIdSetSz,
@@ -751,11 +751,18 @@ static int wc_PKCS7_EcdsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd)
static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd, static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd,
const byte* contentTypeOid, word32 contentTypeOidSz, const byte* contentTypeOid, word32 contentTypeOidSz,
const byte* contentType, word32 contentTypeSz, const byte* contentType, word32 contentTypeSz,
const byte* messageDigestOid, word32 messageDigestOidSz) const byte* messageDigestOid, word32 messageDigestOidSz,
const byte* signingTimeOid, word32 signingTimeOidSz)
{ {
int hashSz; int hashSz;
#ifdef NO_ASN_TIME
PKCS7Attrib cannedAttribs[2]; PKCS7Attrib cannedAttribs[2];
#else
PKCS7Attrib cannedAttribs[3];
byte signingTime[MAX_TIME_STRING_SZ];
int signingTimeSz;
#endif
word32 cannedAttribsCount; word32 cannedAttribsCount;
if (pkcs7 == NULL || esd == NULL || contentTypeOid == NULL || if (pkcs7 == NULL || esd == NULL || contentTypeOid == NULL ||
@@ -766,6 +773,12 @@ static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd,
if (hashSz < 0) if (hashSz < 0)
return hashSz; return hashSz;
#ifndef NO_ASN_TIME
signingTimeSz = GetAsnTimeString(signingTime, sizeof(signingTime));
if (signingTimeSz < 0)
return signingTimeSz;
#endif
cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib); cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib);
cannedAttribs[0].oid = contentTypeOid; cannedAttribs[0].oid = contentTypeOid;
@@ -776,14 +789,25 @@ static int wc_PKCS7_BuildSignedAttributes(PKCS7* pkcs7, ESD* esd,
cannedAttribs[1].oidSz = messageDigestOidSz; cannedAttribs[1].oidSz = messageDigestOidSz;
cannedAttribs[1].value = esd->contentDigest; cannedAttribs[1].value = esd->contentDigest;
cannedAttribs[1].valueSz = hashSz + 2; /* ASN.1 heading */ cannedAttribs[1].valueSz = hashSz + 2; /* ASN.1 heading */
#ifndef NO_ASN_TIME
cannedAttribs[2].oid = signingTimeOid;
cannedAttribs[2].oidSz = signingTimeOidSz;
cannedAttribs[2].value = (byte*)signingTime;
cannedAttribs[2].valueSz = signingTimeSz;
#endif
esd->signedAttribsCount += cannedAttribsCount; esd->signedAttribsCount += cannedAttribsCount;
esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 2, esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[0], 3,
cannedAttribs, cannedAttribsCount); cannedAttribs, cannedAttribsCount);
esd->signedAttribsCount += pkcs7->signedAttribsSz; esd->signedAttribsCount += pkcs7->signedAttribsSz;
#ifdef NO_ASN_TIME
esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4, esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[2], 4,
pkcs7->signedAttribs, pkcs7->signedAttribsSz); pkcs7->signedAttribs, pkcs7->signedAttribsSz);
#else
esd->signedAttribsSz += EncodeAttributes(&esd->signedAttribs[3], 4,
pkcs7->signedAttribs, pkcs7->signedAttribsSz);
#endif
return 0; return 0;
} }
@@ -1074,6 +1098,11 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd,
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, { ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
0x09, 0x04 }; 0x09, 0x04 };
/* signingTime OID () */
byte signingTimeOid[] =
{ ASN_OBJECT_ID, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
0x09, 0x05};
word32 signerInfoSz = 0; word32 signerInfoSz = 0;
word32 totalSz, total2Sz; word32 totalSz, total2Sz;
int idx = 0, ret = 0; int idx = 0, ret = 0;
@@ -1198,7 +1227,8 @@ static int PKCS7_EncodeSigned(PKCS7* pkcs7, ESD* esd,
ret = wc_PKCS7_BuildSignedAttributes(pkcs7, esd, ret = wc_PKCS7_BuildSignedAttributes(pkcs7, esd,
contentTypeOid, sizeof(contentTypeOid), contentTypeOid, sizeof(contentTypeOid),
pkcs7->contentType, pkcs7->contentTypeSz, pkcs7->contentType, pkcs7->contentTypeSz,
messageDigestOid, sizeof(messageDigestOid)); messageDigestOid, sizeof(messageDigestOid),
signingTimeOid, sizeof(signingTimeOid));
if (ret < 0) { if (ret < 0) {
return MEMORY_E; return MEMORY_E;
} }

View File

@@ -305,7 +305,8 @@ enum Misc_ASN {
TRAILING_ZERO = 1, /* Used for size of zero pad */ TRAILING_ZERO = 1, /* Used for size of zero pad */
MIN_VERSION_SZ = 3, /* Min bytes needed for GetMyVersion */ MIN_VERSION_SZ = 3, /* Min bytes needed for GetMyVersion */
#if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \ #if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \
defined(OPENSSL_EXTRA) || defined(HAVE_PKCS7)
MAX_TIME_STRING_SZ = 25, /* Max length of formatted time string */ MAX_TIME_STRING_SZ = 25, /* Max length of formatted time string */
#endif #endif
@@ -990,6 +991,9 @@ typedef struct tm wolfssl_tm;
defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)
WOLFSSL_LOCAL int GetTimeString(byte* date, int format, char* buf, int len); WOLFSSL_LOCAL int GetTimeString(byte* date, int format, char* buf, int len);
#endif #endif
#if !defined(NO_ASN_TIME) && defined(HAVE_PKCS7)
WOLFSSL_LOCAL int GetAsnTimeString(byte* buf, word32 len);
#endif
WOLFSSL_LOCAL int ExtractDate(const unsigned char* date, unsigned char format, WOLFSSL_LOCAL int ExtractDate(const unsigned char* date, unsigned char format,
wolfssl_tm* certTime, int* idx); wolfssl_tm* certTime, int* idx);
WOLFSSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType); WOLFSSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType);