mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-09 13:30:50 +02:00
ae023a5643
Implementation in wolfCrypt OpenSSL compatibility layer in wolfSSL Added tests, certificates, examples.
3532 lines
130 KiB
C
3532 lines
130 KiB
C
/* test_tsp.c
|
|
*
|
|
* Copyright (C) 2006-2026 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfSSL.
|
|
*
|
|
* wolfSSL is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfSSL is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
*/
|
|
|
|
#include <tests/unit.h>
|
|
|
|
#include <tests/api/api.h>
|
|
#include <tests/api/test_tsp.h>
|
|
|
|
#ifdef WOLFSSL_TSP
|
|
#include <wolfssl/wolfcrypt/tsp.h>
|
|
#include <wolfssl/wolfcrypt/error-crypt.h>
|
|
#ifdef HAVE_PKCS7
|
|
#include <wolfssl/wolfcrypt/asn.h>
|
|
#include <wolfssl/wolfcrypt/pkcs7.h>
|
|
#include <wolfssl/wolfcrypt/random.h>
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef WOLFSSL_TSP
|
|
|
|
#ifdef WOLFSSL_TSP_REQUESTER
|
|
/* Hash of message - content is not checked against an algorithm. */
|
|
static const byte tsHashedMsg[32] = {
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
|
};
|
|
|
|
/* Set a message imprint to SHA-256 and the test hash. */
|
|
static void test_tsp_set_hash(TspMessageImprint* mi)
|
|
{
|
|
mi->hashAlgOID = SHA256h;
|
|
XMEMCPY(mi->hash, tsHashedMsg, sizeof(tsHashedMsg));
|
|
mi->hashSz = (word32)sizeof(tsHashedMsg);
|
|
}
|
|
/* 1.3.6.1.4.1.999.1 - test TSA policy. */
|
|
static const byte tsPolicy[] = {
|
|
0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x67, 0x01
|
|
};
|
|
/* Nonce with top bit set to check INTEGER encoding. */
|
|
static const byte tsNonce[] = {
|
|
0xc3, 0x5a, 0x10, 0x42, 0x77, 0x08, 0x99, 0x01
|
|
};
|
|
#endif /* WOLFSSL_TSP_REQUESTER */
|
|
#ifndef NO_SHA256
|
|
#if defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* Serial number with top bit set to check INTEGER encoding. */
|
|
static const byte tsSerial[] = { 0x9a, 0x33 };
|
|
/* Time of test time-stamp. */
|
|
static const byte tsGenTime[] = "20260604120000Z";
|
|
/* Name of TSA: dNSName GeneralName. */
|
|
static const byte tsTsaName[] = { 0x82, 0x03, 't', 's', 'a' };
|
|
#endif /* WOLFSSL_TSP_REQUESTER && WOLFSSL_TSP_RESPONDER */
|
|
#ifdef WOLFSSL_TSP_REQUESTER
|
|
/* DER encoding of minimal TimeStampReq: version 1 and SHA-256 message
|
|
* imprint of tsHashedMsg. */
|
|
static const byte tsMinReqDer[] = {
|
|
0x30, 0x36, /* TimeStampReq */
|
|
0x02, 0x01, 0x01, /* version 1 */
|
|
0x30, 0x31, /* messageImprint */
|
|
0x30, 0x0d, /* hashAlgorithm */
|
|
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, /* sha256 */
|
|
0x04, 0x02, 0x01,
|
|
0x05, 0x00, /* NULL */
|
|
0x04, 0x20, /* hashedMessage */
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
|
};
|
|
#endif /* WOLFSSL_TSP_REQUESTER */
|
|
#endif
|
|
|
|
#endif /* WOLFSSL_TSP */
|
|
|
|
int test_wc_TspRequest_Init(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(WOLFSSL_TSP_REQUESTER)
|
|
TspRequest req;
|
|
|
|
ExpectIntEQ(wc_TspRequest_Init(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
XMEMSET(&req, 0xa5, sizeof(TspRequest));
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
ExpectIntEQ(req.version, WC_TSP_VERSION);
|
|
ExpectIntEQ(req.imprint.hashSz, 0);
|
|
ExpectIntEQ(req.policySz, 0);
|
|
ExpectIntEQ(req.nonceSz, 0);
|
|
ExpectIntEQ(req.certReq, 0);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspRequest_SetHashType(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && !defined(NO_SHA256) && \
|
|
defined(WOLFSSL_TSP_REQUESTER)
|
|
TspRequest req;
|
|
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
|
|
/* Bad argument. */
|
|
ExpectIntEQ(wc_TspRequest_SetHashType(NULL, WC_HASH_TYPE_SHA256),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Hash type that is not a usable algorithm. */
|
|
ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_NONE),
|
|
WC_NO_ERR_TRACE(HASH_TYPE_E));
|
|
|
|
/* SHA-256 sets the algorithm OID and the digest size. */
|
|
ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA256), 0);
|
|
ExpectIntEQ(req.imprint.hashAlgOID, SHA256h);
|
|
ExpectIntEQ(req.imprint.hashSz, WC_SHA256_DIGEST_SIZE);
|
|
|
|
#ifdef WOLFSSL_SHA384
|
|
/* A different algorithm sets a different OID and size. */
|
|
ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA384), 0);
|
|
ExpectIntEQ(req.imprint.hashAlgOID, SHA384h);
|
|
ExpectIntEQ(req.imprint.hashSz, WC_SHA384_DIGEST_SIZE);
|
|
#endif
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspRequest_GetHashType(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && !defined(NO_SHA256) && \
|
|
defined(WOLFSSL_TSP_REQUESTER)
|
|
TspRequest req;
|
|
enum wc_HashType hashType = WC_HASH_TYPE_NONE;
|
|
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA256), 0);
|
|
|
|
/* Bad arguments. */
|
|
ExpectIntEQ(wc_TspRequest_GetHashType(NULL, &hashType),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_GetHashType(&req, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* Round trips with the algorithm that was set. */
|
|
ExpectIntEQ(wc_TspRequest_GetHashType(&req, &hashType), 0);
|
|
ExpectIntEQ(hashType, WC_HASH_TYPE_SHA256);
|
|
|
|
#ifdef WOLFSSL_SHA384
|
|
ExpectIntEQ(wc_TspRequest_SetHashType(&req, WC_HASH_TYPE_SHA384), 0);
|
|
ExpectIntEQ(wc_TspRequest_GetHashType(&req, &hashType), 0);
|
|
ExpectIntEQ(hashType, WC_HASH_TYPE_SHA384);
|
|
#endif
|
|
|
|
/* An OID that is not a known hash algorithm. */
|
|
req.imprint.hashAlgOID = 1;
|
|
ExpectIntEQ(wc_TspRequest_GetHashType(&req, &hashType),
|
|
WC_NO_ERR_TRACE(HASH_TYPE_E));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspRequest_GetSetHash(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && !defined(NO_SHA256) && \
|
|
defined(WOLFSSL_TSP_REQUESTER)
|
|
TspRequest req;
|
|
byte hash[WC_SHA256_DIGEST_SIZE];
|
|
byte out[WC_SHA256_DIGEST_SIZE];
|
|
word32 outSz;
|
|
|
|
XMEMSET(hash, 0x5a, sizeof(hash));
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
|
|
/* Set: bad arguments. */
|
|
ExpectIntEQ(wc_TspRequest_SetHash(NULL, hash, (word32)sizeof(hash)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_SetHash(&req, NULL, (word32)sizeof(hash)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_SetHash(&req, hash, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Hash too big for the message imprint. */
|
|
ExpectIntEQ(wc_TspRequest_SetHash(&req, hash, WC_TSP_MAX_HASH_SZ + 1),
|
|
WC_NO_ERR_TRACE(BUFFER_E));
|
|
|
|
/* Set the hash and length. */
|
|
ExpectIntEQ(wc_TspRequest_SetHash(&req, hash, (word32)sizeof(hash)), 0);
|
|
ExpectIntEQ(req.imprint.hashSz, (word32)sizeof(hash));
|
|
|
|
/* Get: bad arguments. */
|
|
outSz = (word32)sizeof(out);
|
|
ExpectIntEQ(wc_TspRequest_GetHash(NULL, out, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_GetHash(&req, NULL, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_GetHash(&req, out, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Buffer too small. */
|
|
outSz = (word32)sizeof(hash) - 1;
|
|
ExpectIntEQ(wc_TspRequest_GetHash(&req, out, &outSz),
|
|
WC_NO_ERR_TRACE(BUFFER_E));
|
|
|
|
/* Get the hash back - round trips. */
|
|
outSz = (word32)sizeof(out);
|
|
ExpectIntEQ(wc_TspRequest_GetHash(&req, out, &outSz), 0);
|
|
ExpectIntEQ(outSz, (word32)sizeof(hash));
|
|
ExpectBufEQ(out, hash, (int)sizeof(hash));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspRequest_GetSetNonce(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && \
|
|
defined(WOLFSSL_TSP_REQUESTER)
|
|
TspRequest req;
|
|
static const byte nonce[] = { 0x12, 0x34, 0x56, 0x78 };
|
|
static const byte padded[] = { 0x00, 0x00, 0x12, 0x34 };
|
|
static const byte zeros[] = { 0x00, 0x00, 0x00 };
|
|
byte out[16];
|
|
word32 outSz;
|
|
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
|
|
/* Set: bad arguments. */
|
|
ExpectIntEQ(wc_TspRequest_SetNonce(NULL, nonce, (word32)sizeof(nonce)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_SetNonce(&req, NULL, (word32)sizeof(nonce)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_SetNonce(&req, nonce, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Nonce too big for the field. */
|
|
ExpectIntEQ(wc_TspRequest_SetNonce(&req, nonce, MAX_TS_NONCE_SZ + 1),
|
|
WC_NO_ERR_TRACE(BUFFER_E));
|
|
|
|
/* No leading zeros - kept as-is and round trips. */
|
|
ExpectIntEQ(wc_TspRequest_SetNonce(&req, nonce, (word32)sizeof(nonce)), 0);
|
|
ExpectIntEQ(req.nonceSz, (word32)sizeof(nonce));
|
|
outSz = (word32)sizeof(out);
|
|
ExpectIntEQ(wc_TspRequest_GetNonce(&req, out, &outSz), 0);
|
|
ExpectIntEQ(outSz, (word32)sizeof(nonce));
|
|
ExpectBufEQ(out, nonce, (int)sizeof(nonce));
|
|
|
|
/* Leading zero bytes are stripped. */
|
|
ExpectIntEQ(wc_TspRequest_SetNonce(&req, padded, (word32)sizeof(padded)),
|
|
0);
|
|
ExpectIntEQ(req.nonceSz, 2);
|
|
outSz = (word32)sizeof(out);
|
|
ExpectIntEQ(wc_TspRequest_GetNonce(&req, out, &outSz), 0);
|
|
ExpectIntEQ(outSz, 2);
|
|
ExpectIntEQ(out[0], 0x12);
|
|
ExpectIntEQ(out[1], 0x34);
|
|
|
|
/* All zeros becomes a single zero byte. */
|
|
ExpectIntEQ(wc_TspRequest_SetNonce(&req, zeros, (word32)sizeof(zeros)), 0);
|
|
ExpectIntEQ(req.nonceSz, 1);
|
|
outSz = (word32)sizeof(out);
|
|
ExpectIntEQ(wc_TspRequest_GetNonce(&req, out, &outSz), 0);
|
|
ExpectIntEQ(outSz, 1);
|
|
ExpectIntEQ(out[0], 0x00);
|
|
|
|
/* Get: bad arguments. */
|
|
outSz = (word32)sizeof(out);
|
|
ExpectIntEQ(wc_TspRequest_GetNonce(NULL, out, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_GetNonce(&req, NULL, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_GetNonce(&req, out, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Buffer too small for the 1-byte nonce. */
|
|
outSz = 0;
|
|
ExpectIntEQ(wc_TspRequest_GetNonce(&req, out, &outSz),
|
|
WC_NO_ERR_TRACE(BUFFER_E));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspGenerateNonce(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER)
|
|
WC_RNG rng;
|
|
TspRequest req;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
|
|
/* Bad arguments. */
|
|
ExpectIntEQ(wc_TspRequest_GenerateNonce(NULL, &rng, 8),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_GenerateNonce(&req, NULL, 8),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_GenerateNonce(&req, &rng, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_GenerateNonce(&req, &rng,
|
|
MAX_TS_NONCE_SZ + 1), WC_NO_ERR_TRACE(BUFFER_E));
|
|
|
|
/* Generates a minimal positive INTEGER nonce of the requested size. */
|
|
ExpectIntEQ(wc_TspRequest_GenerateNonce(&req, &rng, 8), 0);
|
|
ExpectIntEQ(req.nonceSz, 8);
|
|
ExpectIntLT(req.nonce[0], 0x80); /* positive - top bit clear */
|
|
ExpectIntGT(req.nonce[0], 0x00); /* minimal - non-zero leading byte */
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspRequest_GetSetPolicy(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(WOLFSSL_TSP_REQUESTER)
|
|
TspRequest req;
|
|
/* 1.3.6.1.4.1.999.1 - OBJECT IDENTIFIER content. */
|
|
static const byte policy[] = {
|
|
0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x67, 0x01
|
|
};
|
|
byte big[MAX_OID_SZ + 1];
|
|
byte out[MAX_OID_SZ];
|
|
word32 outSz;
|
|
|
|
XMEMSET(big, 0, sizeof(big));
|
|
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
|
|
/* Set: bad arguments. */
|
|
ExpectIntEQ(wc_TspRequest_SetPolicy(NULL, policy, (word32)sizeof(policy)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_SetPolicy(&req, NULL, (word32)sizeof(policy)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_SetPolicy(&req, policy, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Policy too big for the field. */
|
|
ExpectIntEQ(wc_TspRequest_SetPolicy(&req, big, (word32)sizeof(big)),
|
|
WC_NO_ERR_TRACE(BUFFER_E));
|
|
|
|
/* Set and get round trips - content kept as-is, no stripping. */
|
|
ExpectIntEQ(wc_TspRequest_SetPolicy(&req, policy, (word32)sizeof(policy)),
|
|
0);
|
|
ExpectIntEQ(req.policySz, (word32)sizeof(policy));
|
|
outSz = (word32)sizeof(out);
|
|
ExpectIntEQ(wc_TspRequest_GetPolicy(&req, out, &outSz), 0);
|
|
ExpectIntEQ(outSz, (word32)sizeof(policy));
|
|
ExpectBufEQ(out, policy, (int)sizeof(policy));
|
|
|
|
/* Get: bad arguments. */
|
|
outSz = (word32)sizeof(out);
|
|
ExpectIntEQ(wc_TspRequest_GetPolicy(NULL, out, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_GetPolicy(&req, NULL, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_GetPolicy(&req, out, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Buffer too small for the policy. */
|
|
outSz = (word32)sizeof(policy) - 1;
|
|
ExpectIntEQ(wc_TspRequest_GetPolicy(&req, out, &outSz),
|
|
WC_NO_ERR_TRACE(BUFFER_E));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspRequest_GetSetCertReq(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
/* The requester both sets and gets certReq - runs in a requester build. */
|
|
#if defined(WOLFSSL_TSP) && defined(WOLFSSL_TSP_REQUESTER)
|
|
TspRequest req;
|
|
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
|
|
/* Defaults to not requesting the TSA certificate. */
|
|
ExpectIntEQ(wc_TspRequest_GetCertReq(&req), 0);
|
|
|
|
/* Set requests the certificate and round trips through the getter. */
|
|
wc_TspRequest_SetCertReq(&req, 1);
|
|
ExpectIntEQ(wc_TspRequest_GetCertReq(&req), 1);
|
|
|
|
/* Any non-zero value is normalized to 1. */
|
|
wc_TspRequest_SetCertReq(&req, 5);
|
|
ExpectIntEQ(wc_TspRequest_GetCertReq(&req), 1);
|
|
ExpectIntEQ(req.certReq, 1);
|
|
|
|
/* Clear the request. */
|
|
wc_TspRequest_SetCertReq(&req, 0);
|
|
ExpectIntEQ(wc_TspRequest_GetCertReq(&req), 0);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspRequest_Encode(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && !defined(NO_SHA256) && \
|
|
defined(WOLFSSL_TSP_REQUESTER)
|
|
TspRequest req;
|
|
byte enc[256];
|
|
word32 encSz;
|
|
word32 sz;
|
|
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
test_tsp_set_hash(&req.imprint);
|
|
|
|
/* Bad arguments. */
|
|
encSz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspRequest_Encode(NULL, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, enc, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Message imprint required. */
|
|
req.imprint.hashSz = 0;
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Hash too long. */
|
|
req.imprint.hashSz = WC_TSP_MAX_HASH_SZ + 1;
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
req.imprint.hashSz = (word32)sizeof(tsHashedMsg);
|
|
/* Policy too long. */
|
|
req.policySz = MAX_OID_SZ + 1;
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
req.policySz = 0;
|
|
/* Unknown hash algorithm. */
|
|
req.imprint.hashAlgOID = 1;
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &encSz),
|
|
WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E));
|
|
req.imprint.hashAlgOID = SHA256h;
|
|
/* Nonce with a leading zero byte - not allowed. */
|
|
{
|
|
static const byte paddedNonce[] = { 0x00, 0x13 };
|
|
|
|
XMEMCPY(req.nonce, paddedNonce, sizeof(paddedNonce));
|
|
req.nonceSz = (word32)sizeof(paddedNonce);
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Nonce too long - not allowed. */
|
|
req.nonceSz = MAX_TS_NONCE_SZ + 1;
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
req.nonceSz = 0;
|
|
}
|
|
|
|
/* Get length of encoding only. */
|
|
encSz = 0;
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, NULL, &encSz), 0);
|
|
ExpectIntEQ(encSz, (word32)sizeof(tsMinReqDer));
|
|
/* Buffer too small. */
|
|
sz = encSz - 1;
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &sz),
|
|
WC_NO_ERR_TRACE(BUFFER_E));
|
|
/* Check minimal encoding against expected DER. */
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &sz), 0);
|
|
ExpectIntEQ(sz, (word32)sizeof(tsMinReqDer));
|
|
ExpectBufEQ(enc, tsMinReqDer, (int)sizeof(tsMinReqDer));
|
|
|
|
/* All optional fields included. */
|
|
XMEMCPY(req.policy, tsPolicy, sizeof(tsPolicy));
|
|
req.policySz = (word32)sizeof(tsPolicy);
|
|
XMEMCPY(req.nonce, tsNonce, sizeof(tsNonce));
|
|
req.nonceSz = (word32)sizeof(tsNonce);
|
|
req.certReq = 1;
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &sz), 0);
|
|
ExpectIntGT(sz, (word32)sizeof(tsMinReqDer));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspRequest_Decode(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && !defined(NO_SHA256) && \
|
|
defined(WOLFSSL_TSP_REQUESTER)
|
|
/* Minimal TimeStampReq without NULL hash algorithm parameters. */
|
|
static const byte noNullDer[] = {
|
|
0x30, 0x34,
|
|
0x02, 0x01, 0x01,
|
|
0x30, 0x2f,
|
|
0x30, 0x0b,
|
|
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
|
|
0x04, 0x20,
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
|
};
|
|
TspRequest req;
|
|
TspRequest reqDec;
|
|
byte enc[256];
|
|
word32 sz;
|
|
|
|
/* Bad arguments. */
|
|
ExpectIntEQ(wc_TspRequest_Decode(NULL, tsMinReqDer,
|
|
(word32)sizeof(tsMinReqDer)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_Decode(&reqDec, NULL,
|
|
(word32)sizeof(tsMinReqDer)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspRequest_Decode(&reqDec, tsMinReqDer, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* Minimal request. */
|
|
ExpectIntEQ(wc_TspRequest_Decode(&reqDec, tsMinReqDer,
|
|
(word32)sizeof(tsMinReqDer)), 0);
|
|
ExpectIntEQ(reqDec.version, WC_TSP_VERSION);
|
|
ExpectIntEQ(reqDec.imprint.hashAlgOID, SHA256h);
|
|
ExpectIntEQ(reqDec.imprint.hashSz, (word32)sizeof(tsHashedMsg));
|
|
ExpectBufEQ(reqDec.imprint.hash, tsHashedMsg,
|
|
(int)sizeof(tsHashedMsg));
|
|
ExpectIntEQ(reqDec.policySz, 0);
|
|
ExpectIntEQ(reqDec.nonceSz, 0);
|
|
ExpectIntEQ(reqDec.certReq, 0);
|
|
|
|
/* Hash algorithm parameters not present. */
|
|
ExpectIntEQ(wc_TspRequest_Decode(&reqDec, noNullDer,
|
|
(word32)sizeof(noNullDer)), 0);
|
|
ExpectIntEQ(reqDec.imprint.hashAlgOID, SHA256h);
|
|
|
|
/* Truncated encoding. */
|
|
ExpectIntLT(wc_TspRequest_Decode(&reqDec, tsMinReqDer,
|
|
(word32)sizeof(tsMinReqDer) - 1), 0);
|
|
/* Trailing data not allowed. */
|
|
XMEMCPY(enc, tsMinReqDer, sizeof(tsMinReqDer));
|
|
enc[sizeof(tsMinReqDer)] = 0x00;
|
|
ExpectIntLT(wc_TspRequest_Decode(&reqDec, enc,
|
|
(word32)sizeof(tsMinReqDer) + 1), 0);
|
|
|
|
/* Request with extensions is not supported. */
|
|
{
|
|
static const byte extsReqDer[] = {
|
|
0x30, 0x45, /* TimeStampReq */
|
|
0x02, 0x01, 0x01, /* version 1 */
|
|
0x30, 0x31, /* messageImprint */
|
|
0x30, 0x0d, /* hashAlgorithm */
|
|
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, /* sha256 */
|
|
0x04, 0x02, 0x01,
|
|
0x05, 0x00, /* NULL */
|
|
0x04, 0x20, /* hashedMessage */
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
|
0xa0, 0x0d, /* extensions */
|
|
0x30, 0x0b, 0x06, 0x02, 0x2a, 0x03, /* OID 1.2.3 */
|
|
0x04, 0x05, 0x01, 0x02, 0x03, 0x04, 0x05 /* value */
|
|
};
|
|
|
|
ExpectIntEQ(wc_TspRequest_Decode(&reqDec, extsReqDer,
|
|
(word32)sizeof(extsReqDer)), WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
}
|
|
|
|
/* Request with an empty hash is invalid. */
|
|
{
|
|
static const byte emptyHashDer[] = {
|
|
0x30, 0x16, /* TimeStampReq */
|
|
0x02, 0x01, 0x01, /* version 1 */
|
|
0x30, 0x11, /* messageImprint */
|
|
0x30, 0x0d, /* hashAlgorithm */
|
|
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, /* sha256 */
|
|
0x04, 0x02, 0x01,
|
|
0x05, 0x00, /* NULL */
|
|
0x04, 0x00 /* hashedMessage */
|
|
};
|
|
|
|
ExpectIntEQ(wc_TspRequest_Decode(&reqDec, emptyHashDer,
|
|
(word32)sizeof(emptyHashDer)), WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
}
|
|
|
|
/* Request with an unsupported version is rejected - RFC 3161, 2.4.1. */
|
|
{
|
|
/* tsMinReqDer with the version INTEGER changed from 1 to 2. */
|
|
XMEMCPY(enc, tsMinReqDer, sizeof(tsMinReqDer));
|
|
enc[4] = 0x02; /* version = 2 */
|
|
ExpectIntEQ(wc_TspRequest_Decode(&reqDec, enc,
|
|
(word32)sizeof(tsMinReqDer)), WC_NO_ERR_TRACE(ASN_VERSION_E));
|
|
enc[4] = 0x00; /* version = 0 */
|
|
ExpectIntEQ(wc_TspRequest_Decode(&reqDec, enc,
|
|
(word32)sizeof(tsMinReqDer)), WC_NO_ERR_TRACE(ASN_VERSION_E));
|
|
}
|
|
|
|
/* Nonce of zero is one zero byte. */
|
|
{
|
|
static const byte zeroNonce[] = { 0x00 };
|
|
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
test_tsp_set_hash(&req.imprint);
|
|
XMEMCPY(req.nonce, zeroNonce, sizeof(zeroNonce));
|
|
req.nonceSz = (word32)sizeof(zeroNonce);
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspRequest_Decode(&reqDec, enc, sz), 0);
|
|
ExpectIntEQ(reqDec.nonceSz, 1);
|
|
if (EXPECT_SUCCESS()) {
|
|
ExpectIntEQ(reqDec.nonce[0], 0x00);
|
|
}
|
|
}
|
|
|
|
/* Round trip all optional fields. */
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
test_tsp_set_hash(&req.imprint);
|
|
XMEMCPY(req.policy, tsPolicy, sizeof(tsPolicy));
|
|
req.policySz = (word32)sizeof(tsPolicy);
|
|
XMEMCPY(req.nonce, tsNonce, sizeof(tsNonce));
|
|
req.nonceSz = (word32)sizeof(tsNonce);
|
|
req.certReq = 1;
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspRequest_Decode(&reqDec, enc, sz), 0);
|
|
ExpectIntEQ(reqDec.policySz, (word32)sizeof(tsPolicy));
|
|
ExpectBufEQ(reqDec.policy, tsPolicy, (int)sizeof(tsPolicy));
|
|
ExpectIntEQ(reqDec.nonceSz, (word32)sizeof(tsNonce));
|
|
ExpectBufEQ(reqDec.nonce, tsNonce, (int)sizeof(tsNonce));
|
|
ExpectIntEQ(reqDec.certReq, 1);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_Init(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(WOLFSSL_TSP_RESPONDER)
|
|
TspTstInfo tst;
|
|
|
|
ExpectIntEQ(wc_TspTstInfo_Init(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
XMEMSET(&tst, 0xa5, sizeof(TspTstInfo));
|
|
ExpectIntEQ(wc_TspTstInfo_Init(&tst), 0);
|
|
ExpectIntEQ(tst.version, WC_TSP_VERSION);
|
|
ExpectNull(tst.policy);
|
|
ExpectNull(tst.serial);
|
|
ExpectNull(tst.genTime);
|
|
ExpectIntEQ(tst.accuracy.seconds, 0);
|
|
ExpectIntEQ(tst.ordering, 0);
|
|
ExpectNull(tst.nonce);
|
|
ExpectNull(tst.tsa);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_GetSetSerial(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
TspTstInfo tst;
|
|
static const byte serial[] = { 0x9a, 0x33, 0x10 };
|
|
static const byte padded[] = { 0x00, 0x00, 0x9a, 0x33 };
|
|
static const byte zeros[] = { 0x00, 0x00, 0x00 };
|
|
const byte* out = NULL;
|
|
word32 outSz = 0;
|
|
|
|
ExpectIntEQ(wc_TspTstInfo_Init(&tst), 0);
|
|
|
|
/* No serial on a freshly initialized TSTInfo - Get reports it absent. */
|
|
out = serial;
|
|
outSz = 99;
|
|
ExpectIntEQ(wc_TspTstInfo_GetSerial(&tst, &out, &outSz), 0);
|
|
ExpectNull(out);
|
|
ExpectIntEQ(outSz, 0);
|
|
|
|
/* Set: bad arguments. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetSerial(NULL, serial, (word32)sizeof(serial)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetSerial(&tst, NULL, (word32)sizeof(serial)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetSerial(&tst, serial, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* No leading zeros - referenced as-is and round trips. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetSerial(&tst, serial, (word32)sizeof(serial)),
|
|
0);
|
|
ExpectIntEQ(wc_TspTstInfo_GetSerial(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, serial);
|
|
ExpectIntEQ(outSz, (word32)sizeof(serial));
|
|
|
|
/* Leading zero bytes are stripped - references past them. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetSerial(&tst, padded, (word32)sizeof(padded)),
|
|
0);
|
|
ExpectIntEQ(wc_TspTstInfo_GetSerial(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, padded + 2);
|
|
ExpectIntEQ(outSz, 2);
|
|
ExpectIntEQ(out[0], 0x9a);
|
|
ExpectIntEQ(out[1], 0x33);
|
|
|
|
/* All zeros becomes a single zero byte. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetSerial(&tst, zeros, (word32)sizeof(zeros)), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_GetSerial(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, zeros + 2);
|
|
ExpectIntEQ(outSz, 1);
|
|
ExpectIntEQ(out[0], 0x00);
|
|
|
|
/* Get: bad arguments. */
|
|
ExpectIntEQ(wc_TspTstInfo_GetSerial(NULL, &out, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetSerial(&tst, NULL, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetSerial(&tst, &out, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
#if defined(WOLFSSL_TSP) && !defined(NO_SHA256) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* Fill a TSTInfo with the required fields. */
|
|
static void test_tsp_set_tstinfo(TspTstInfo* tst)
|
|
{
|
|
(void)wc_TspTstInfo_Init(tst);
|
|
tst->policy = tsPolicy;
|
|
tst->policySz = (word32)sizeof(tsPolicy);
|
|
test_tsp_set_hash(&tst->imprint);
|
|
tst->serial = tsSerial;
|
|
tst->serialSz = (word32)sizeof(tsSerial);
|
|
tst->genTime = tsGenTime;
|
|
tst->genTimeSz = (word32)sizeof(tsGenTime) - 1;
|
|
}
|
|
#endif
|
|
|
|
int test_wc_TspTstInfo_Getters(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && !defined(NO_SHA256) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
TspTstInfo tst;
|
|
const byte* out = NULL;
|
|
word32 outSz = 0;
|
|
word32 hashOID = 0;
|
|
word32 seconds = 0;
|
|
word16 millis = 0;
|
|
word16 micros = 0;
|
|
|
|
test_tsp_set_tstinfo(&tst);
|
|
tst.accuracy.seconds = 1;
|
|
tst.accuracy.millis = 500;
|
|
tst.accuracy.micros = 250;
|
|
tst.nonce = tsNonce;
|
|
tst.nonceSz = (word32)sizeof(tsNonce);
|
|
tst.tsa = tsTsaName;
|
|
tst.tsaSz = (word32)sizeof(tsTsaName);
|
|
|
|
/* Policy. */
|
|
ExpectIntEQ(wc_TspTstInfo_GetPolicy(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, tsPolicy);
|
|
ExpectIntEQ(outSz, (word32)sizeof(tsPolicy));
|
|
/* Message imprint. */
|
|
ExpectIntEQ(wc_TspTstInfo_GetMsgImprint(&tst, &hashOID, &out, &outSz), 0);
|
|
ExpectIntEQ(hashOID, SHA256h);
|
|
ExpectIntEQ(outSz, (word32)sizeof(tsHashedMsg));
|
|
ExpectBufEQ(out, tsHashedMsg, (int)sizeof(tsHashedMsg));
|
|
/* All message imprint outputs are optional. */
|
|
ExpectIntEQ(wc_TspTstInfo_GetMsgImprint(&tst, NULL, NULL, NULL), 0);
|
|
/* Time of the time-stamp. */
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTime(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, tsGenTime);
|
|
ExpectIntEQ(outSz, (word32)sizeof(tsGenTime) - 1);
|
|
/* Accuracy. */
|
|
ExpectIntEQ(wc_TspTstInfo_GetAccuracy(&tst, &seconds, &millis, µs), 0);
|
|
ExpectIntEQ(seconds, 1);
|
|
ExpectIntEQ(millis, 500);
|
|
ExpectIntEQ(micros, 250);
|
|
/* All accuracy outputs are optional. */
|
|
ExpectIntEQ(wc_TspTstInfo_GetAccuracy(&tst, NULL, NULL, NULL), 0);
|
|
/* Nonce. */
|
|
ExpectIntEQ(wc_TspTstInfo_GetNonce(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, tsNonce);
|
|
ExpectIntEQ(outSz, (word32)sizeof(tsNonce));
|
|
/* TSA name. */
|
|
ExpectIntEQ(wc_TspTstInfo_GetTsa(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, tsTsaName);
|
|
ExpectIntEQ(outSz, (word32)sizeof(tsTsaName));
|
|
|
|
/* On a freshly initialized TSTInfo the optional fields are absent - the
|
|
* getters succeed and report empty values, not an error. */
|
|
ExpectIntEQ(wc_TspTstInfo_Init(&tst), 0);
|
|
out = tsPolicy;
|
|
outSz = 99;
|
|
ExpectIntEQ(wc_TspTstInfo_GetPolicy(&tst, &out, &outSz), 0);
|
|
ExpectNull(out);
|
|
ExpectIntEQ(outSz, 0);
|
|
out = tsGenTime;
|
|
outSz = 99;
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTime(&tst, &out, &outSz), 0);
|
|
ExpectNull(out);
|
|
ExpectIntEQ(outSz, 0);
|
|
out = tsNonce;
|
|
outSz = 99;
|
|
ExpectIntEQ(wc_TspTstInfo_GetNonce(&tst, &out, &outSz), 0);
|
|
ExpectNull(out);
|
|
ExpectIntEQ(outSz, 0);
|
|
out = tsTsaName;
|
|
outSz = 99;
|
|
ExpectIntEQ(wc_TspTstInfo_GetTsa(&tst, &out, &outSz), 0);
|
|
ExpectNull(out);
|
|
ExpectIntEQ(outSz, 0);
|
|
hashOID = 99;
|
|
outSz = 99;
|
|
ExpectIntEQ(wc_TspTstInfo_GetMsgImprint(&tst, &hashOID, &out, &outSz), 0);
|
|
ExpectIntEQ(hashOID, 0);
|
|
ExpectIntEQ(outSz, 0);
|
|
seconds = 99;
|
|
millis = 99;
|
|
micros = 99;
|
|
ExpectIntEQ(wc_TspTstInfo_GetAccuracy(&tst, &seconds, &millis, µs), 0);
|
|
ExpectIntEQ(seconds, 0);
|
|
ExpectIntEQ(millis, 0);
|
|
ExpectIntEQ(micros, 0);
|
|
|
|
/* Bad arguments. */
|
|
ExpectIntEQ(wc_TspTstInfo_GetPolicy(NULL, &out, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetPolicy(&tst, NULL, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetPolicy(&tst, &out, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetMsgImprint(NULL, &hashOID, &out, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTime(NULL, &out, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTime(&tst, NULL, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTime(&tst, &out, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetAccuracy(NULL, &seconds, &millis, µs),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetNonce(NULL, &out, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetNonce(&tst, NULL, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetNonce(&tst, &out, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetTsa(NULL, &out, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetTsa(&tst, NULL, &outSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetTsa(&tst, &out, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_Setters(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
TspTstInfo tst;
|
|
/* 1.3.6.1.4.1.999.1 - OBJECT IDENTIFIER content. */
|
|
static const byte policy[] = {
|
|
0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x67, 0x01
|
|
};
|
|
static const byte hash[] = { 0xde, 0xad, 0xbe, 0xef };
|
|
static const byte genTime[] = "20260610120000Z";
|
|
static const byte nonce[] = { 0x12, 0x34 };
|
|
/* Name of TSA: dNSName GeneralName. */
|
|
static const byte tsa[] = { 0x82, 0x03, 't', 's', 'a' };
|
|
static const byte padded[] = { 0x00, 0x00, 0x12, 0x34 };
|
|
byte bigHash[WC_TSP_MAX_HASH_SZ + 1];
|
|
const byte* out = NULL;
|
|
word32 outSz = 0;
|
|
word32 hashOID = 0;
|
|
word32 seconds = 0;
|
|
word16 millis = 0;
|
|
word16 micros = 0;
|
|
|
|
XMEMSET(bigHash, 0, sizeof(bigHash));
|
|
ExpectIntEQ(wc_TspTstInfo_Init(&tst), 0);
|
|
|
|
/* Policy - referenced, round trips through the getter. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetPolicy(NULL, policy, (word32)sizeof(policy)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetPolicy(&tst, NULL, (word32)sizeof(policy)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetPolicy(&tst, policy, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetPolicy(&tst, policy, (word32)sizeof(policy)),
|
|
0);
|
|
ExpectIntEQ(wc_TspTstInfo_GetPolicy(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, policy);
|
|
ExpectIntEQ(outSz, (word32)sizeof(policy));
|
|
|
|
/* Message imprint - copied, too big rejected, round trips. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetMsgImprint(NULL, SHA256h, hash,
|
|
(word32)sizeof(hash)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetMsgImprint(&tst, SHA256h, NULL,
|
|
(word32)sizeof(hash)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetMsgImprint(&tst, SHA256h, hash, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetMsgImprint(&tst, SHA256h, bigHash,
|
|
(word32)sizeof(bigHash)), WC_NO_ERR_TRACE(BUFFER_E));
|
|
ExpectIntEQ(wc_TspTstInfo_SetMsgImprint(&tst, SHA256h, hash,
|
|
(word32)sizeof(hash)), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_GetMsgImprint(&tst, &hashOID, &out, &outSz), 0);
|
|
ExpectIntEQ(hashOID, SHA256h);
|
|
ExpectIntEQ(outSz, (word32)sizeof(hash));
|
|
ExpectBufEQ(out, hash, (int)sizeof(hash));
|
|
|
|
/* Time of the time-stamp - referenced, round trips. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetGenTime(NULL, genTime,
|
|
(word32)sizeof(genTime) - 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetGenTime(&tst, NULL,
|
|
(word32)sizeof(genTime) - 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetGenTime(&tst, genTime, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetGenTime(&tst, genTime,
|
|
(word32)sizeof(genTime) - 1), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTime(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, genTime);
|
|
ExpectIntEQ(outSz, (word32)sizeof(genTime) - 1);
|
|
|
|
/* Accuracy - values round trip. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetAccuracy(NULL, 1, 500, 250),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetAccuracy(&tst, 1, 500, 250), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_GetAccuracy(&tst, &seconds, &millis, µs), 0);
|
|
ExpectIntEQ(seconds, 1);
|
|
ExpectIntEQ(millis, 500);
|
|
ExpectIntEQ(micros, 250);
|
|
|
|
/* Nonce - referenced, leading zeros stripped, round trips. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetNonce(NULL, nonce, (word32)sizeof(nonce)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetNonce(&tst, NULL, (word32)sizeof(nonce)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetNonce(&tst, nonce, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetNonce(&tst, nonce, (word32)sizeof(nonce)), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_GetNonce(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, nonce);
|
|
ExpectIntEQ(outSz, (word32)sizeof(nonce));
|
|
ExpectIntEQ(wc_TspTstInfo_SetNonce(&tst, padded, (word32)sizeof(padded)),
|
|
0);
|
|
ExpectIntEQ(wc_TspTstInfo_GetNonce(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, padded + 2);
|
|
ExpectIntEQ(outSz, 2);
|
|
|
|
/* TSA name - referenced, round trips. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetTsa(NULL, tsa, (word32)sizeof(tsa)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetTsa(&tst, NULL, (word32)sizeof(tsa)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetTsa(&tst, tsa, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetTsa(&tst, tsa, (word32)sizeof(tsa)), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_GetTsa(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, tsa);
|
|
ExpectIntEQ(outSz, (word32)sizeof(tsa));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_Encode(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && !defined(NO_SHA256) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
TspTstInfo tst;
|
|
TspTstInfo tstDec;
|
|
byte enc[256];
|
|
word32 encSz;
|
|
word32 sz;
|
|
|
|
test_tsp_set_tstinfo(&tst);
|
|
|
|
/* Bad arguments. */
|
|
encSz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(NULL, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Required fields. */
|
|
tst.policy = NULL;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
tst.policy = tsPolicy;
|
|
/* Empty policy - not allowed. */
|
|
tst.policySz = 0;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
tst.policySz = (word32)sizeof(tsPolicy);
|
|
/* Empty genTime - not allowed. */
|
|
tst.genTimeSz = 0;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* genTime must end in Z. */
|
|
tst.genTime = (const byte*)"20260604120000";
|
|
tst.genTimeSz = 14;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* genTime fraction of seconds must not have a trailing zero. */
|
|
tst.genTime = (const byte*)"20260604120000.50Z";
|
|
tst.genTimeSz = 18;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* genTime fraction of seconds must not be empty. */
|
|
tst.genTime = (const byte*)"20260604120000.Z";
|
|
tst.genTimeSz = 16;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* genTime with a fraction of seconds is valid. */
|
|
tst.genTime = (const byte*)"20260604120000.5Z";
|
|
tst.genTimeSz = 17;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz), 0);
|
|
encSz = (word32)sizeof(enc);
|
|
tst.genTime = tsGenTime;
|
|
tst.genTimeSz = (word32)sizeof(tsGenTime) - 1;
|
|
/* Empty TSA name - not allowed. */
|
|
tst.tsa = tsTsaName;
|
|
tst.tsaSz = 0;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
tst.tsa = NULL;
|
|
tst.imprint.hashSz = 0;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Hash too long. */
|
|
tst.imprint.hashSz = WC_TSP_MAX_HASH_SZ + 1;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
tst.imprint.hashSz = (word32)sizeof(tsHashedMsg);
|
|
tst.serial = NULL;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
tst.serial = tsSerial;
|
|
/* Serial number and nonce with a leading zero byte - not allowed. */
|
|
{
|
|
static const byte paddedNum[] = { 0x00, 0x13 };
|
|
|
|
tst.serial = paddedNum;
|
|
tst.serialSz = (word32)sizeof(paddedNum);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Empty serial number - not allowed. */
|
|
tst.serialSz = 0;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
tst.serial = tsSerial;
|
|
tst.serialSz = (word32)sizeof(tsSerial);
|
|
tst.nonce = paddedNum;
|
|
tst.nonceSz = (word32)sizeof(paddedNum);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
tst.nonce = NULL;
|
|
tst.nonceSz = 0;
|
|
}
|
|
/* Accuracy range. */
|
|
tst.accuracy.millis = 1000;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
tst.accuracy.millis = 0;
|
|
tst.accuracy.micros = 1000;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
tst.accuracy.micros = 0;
|
|
/* Unknown hash algorithm. */
|
|
tst.imprint.hashAlgOID = 1;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &encSz),
|
|
WC_NO_ERR_TRACE(ASN_UNKNOWN_OID_E));
|
|
tst.imprint.hashAlgOID = SHA256h;
|
|
|
|
/* Get length of encoding only. */
|
|
encSz = 0;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, NULL, &encSz), 0);
|
|
ExpectIntGT(encSz, 0);
|
|
/* Buffer too small. */
|
|
sz = encSz - 1;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &sz),
|
|
WC_NO_ERR_TRACE(BUFFER_E));
|
|
/* Minimal TSTInfo round trip. */
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &sz), 0);
|
|
ExpectIntEQ(sz, encSz);
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, enc, sz), 0);
|
|
ExpectIntEQ(tstDec.accuracy.seconds, 0);
|
|
ExpectIntEQ(tstDec.accuracy.millis, 0);
|
|
ExpectIntEQ(tstDec.accuracy.micros, 0);
|
|
ExpectIntEQ(tstDec.ordering, 0);
|
|
ExpectNull(tstDec.nonce);
|
|
ExpectNull(tstDec.tsa);
|
|
|
|
/* Accuracy values that need 2 bytes and a leading zero byte. */
|
|
tst.accuracy.seconds = 70000;
|
|
tst.accuracy.millis = 128;
|
|
tst.accuracy.micros = 999;
|
|
/* All optional fields included. */
|
|
tst.ordering = 1;
|
|
tst.nonce = tsNonce;
|
|
tst.nonceSz = (word32)sizeof(tsNonce);
|
|
tst.tsa = tsTsaName;
|
|
tst.tsaSz = (word32)sizeof(tsTsaName);
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, enc, sz), 0);
|
|
ExpectIntEQ(tstDec.accuracy.seconds, 70000);
|
|
ExpectIntEQ(tstDec.accuracy.millis, 128);
|
|
ExpectIntEQ(tstDec.accuracy.micros, 999);
|
|
ExpectIntEQ(tstDec.ordering, 1);
|
|
|
|
/* Accuracy with only seconds. */
|
|
tst.accuracy.seconds = 1;
|
|
tst.accuracy.millis = 0;
|
|
tst.accuracy.micros = 0;
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, enc, sz), 0);
|
|
ExpectIntEQ(tstDec.accuracy.seconds, 1);
|
|
ExpectIntEQ(tstDec.accuracy.millis, 0);
|
|
ExpectIntEQ(tstDec.accuracy.micros, 0);
|
|
|
|
/* Accuracy with only millis. */
|
|
tst.accuracy.seconds = 0;
|
|
tst.accuracy.millis = 500;
|
|
tst.accuracy.micros = 0;
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, enc, sz), 0);
|
|
ExpectIntEQ(tstDec.accuracy.seconds, 0);
|
|
ExpectIntEQ(tstDec.accuracy.millis, 500);
|
|
ExpectIntEQ(tstDec.accuracy.micros, 0);
|
|
|
|
/* Accuracy seconds needing a zero byte to be positive. */
|
|
tst.accuracy.seconds = 200;
|
|
tst.accuracy.millis = 0;
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, enc, sz), 0);
|
|
ExpectIntEQ(tstDec.accuracy.seconds, 200);
|
|
/* Accuracy seconds of the maximum encoding length. */
|
|
tst.accuracy.seconds = 0x80000000UL;
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, enc, sz), 0);
|
|
ExpectIntEQ(tstDec.accuracy.seconds, 0x80000000UL);
|
|
|
|
#if !defined(NO_ASN_TIME) && !defined(USER_TIME) && !defined(TIME_OVERRIDES)
|
|
/* Use current time when genTime not set. */
|
|
tst.genTime = NULL;
|
|
tst.genTimeSz = 0;
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, enc, sz), 0);
|
|
ExpectIntGE(tstDec.genTimeSz, 15);
|
|
if (EXPECT_SUCCESS()) {
|
|
ExpectIntEQ(tstDec.genTime[tstDec.genTimeSz - 1], 'Z');
|
|
}
|
|
#endif
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_Decode(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && !defined(NO_SHA256) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
TspTstInfo tst;
|
|
TspTstInfo tstDec;
|
|
byte enc[256];
|
|
word32 sz;
|
|
|
|
test_tsp_set_tstinfo(&tst);
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &sz), 0);
|
|
|
|
/* Bad arguments. */
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(NULL, enc, sz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, NULL, sz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, enc, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* Truncated encoding. */
|
|
ExpectIntLT(wc_TspTstInfo_Decode(&tstDec, enc, sz - 1), 0);
|
|
/* Trailing data not allowed. */
|
|
enc[sz] = 0x00;
|
|
ExpectIntLT(wc_TspTstInfo_Decode(&tstDec, enc, sz + 1), 0);
|
|
|
|
/* TSTInfo with extensions is not supported. */
|
|
{
|
|
static const byte extsTstDer[] = {
|
|
0x30, 0x62, /* TSTInfo */
|
|
0x02, 0x01, 0x01, /* version 1 */
|
|
0x06, 0x08, /* policy */
|
|
0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x67, 0x01,
|
|
0x30, 0x31, /* messageImprint */
|
|
0x30, 0x0d, /* hashAlgorithm */
|
|
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, /* sha256 */
|
|
0x04, 0x02, 0x01,
|
|
0x05, 0x00, /* NULL */
|
|
0x04, 0x20, /* hashedMessage */
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
|
0x02, 0x02, 0x9a, 0x33, /* serialNumber */
|
|
0x18, 0x0f, /* genTime */
|
|
'2', '0', '2', '6', '0', '6', '0', '4',
|
|
'1', '2', '0', '0', '0', '0', 'Z',
|
|
0xa1, 0x0b, /* extensions */
|
|
0x30, 0x09, 0x06, 0x02, 0x2a, 0x03, /* OID 1.2.3 */
|
|
0x04, 0x03, 0x01, 0x02, 0x03 /* value */
|
|
};
|
|
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, extsTstDer,
|
|
(word32)sizeof(extsTstDer)), WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
}
|
|
|
|
/* Accuracy millis and micros must be 1..999 when present. */
|
|
{
|
|
static const byte accTstDer[] = {
|
|
0x30, 0x5b, /* TSTInfo */
|
|
0x02, 0x01, 0x01, /* version 1 */
|
|
0x06, 0x08, /* policy */
|
|
0x2b, 0x06, 0x01, 0x04, 0x01, 0x87, 0x67, 0x01,
|
|
0x30, 0x31, /* messageImprint */
|
|
0x30, 0x0d, /* hashAlgorithm */
|
|
0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, /* sha256 */
|
|
0x04, 0x02, 0x01,
|
|
0x05, 0x00, /* NULL */
|
|
0x04, 0x20, /* hashedMessage */
|
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
|
0x02, 0x02, 0x9a, 0x33, /* serialNumber */
|
|
0x18, 0x0f, /* genTime */
|
|
'2', '0', '2', '6', '0', '6', '0', '4',
|
|
'1', '2', '0', '0', '0', '0', 'Z',
|
|
0x30, 0x04, /* accuracy */
|
|
0x80, 0x02, 0x03, 0xe7 /* millis 999 */
|
|
};
|
|
byte accEnc[sizeof(accTstDer)];
|
|
|
|
XMEMCPY(accEnc, accTstDer, sizeof(accTstDer));
|
|
/* Maximum millis value decodes. */
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, accEnc,
|
|
(word32)sizeof(accEnc)), 0);
|
|
ExpectIntEQ(tstDec.accuracy.millis, 999);
|
|
/* millis of 1000 - out of range. */
|
|
accEnc[sizeof(accEnc) - 1] = 0xe8;
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, accEnc,
|
|
(word32)sizeof(accEnc)), WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
/* micros of 1000 - out of range. */
|
|
accEnc[sizeof(accEnc) - 4] = 0x81;
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, accEnc,
|
|
(word32)sizeof(accEnc)), WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
/* micros of zero - out of range. */
|
|
accEnc[sizeof(accEnc) - 2] = 0x00;
|
|
accEnc[sizeof(accEnc) - 1] = 0x00;
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, accEnc,
|
|
(word32)sizeof(accEnc)), WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
/* genTime not ending in Z - invalid. */
|
|
XMEMCPY(accEnc, accTstDer, sizeof(accTstDer));
|
|
accEnc[sizeof(accEnc) - 7] = '0';
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, accEnc,
|
|
(word32)sizeof(accEnc)), WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
}
|
|
|
|
/* Check decoded fields. */
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, enc, sz), 0);
|
|
ExpectIntEQ(tstDec.version, WC_TSP_VERSION);
|
|
ExpectIntEQ(tstDec.policySz, (word32)sizeof(tsPolicy));
|
|
ExpectBufEQ(tstDec.policy, tsPolicy, (int)sizeof(tsPolicy));
|
|
ExpectIntEQ(tstDec.imprint.hashAlgOID, SHA256h);
|
|
ExpectIntEQ(tstDec.imprint.hashSz, (word32)sizeof(tsHashedMsg));
|
|
ExpectBufEQ(tstDec.imprint.hash, tsHashedMsg,
|
|
(int)sizeof(tsHashedMsg));
|
|
ExpectIntEQ(tstDec.serialSz, (word32)sizeof(tsSerial));
|
|
ExpectBufEQ(tstDec.serial, tsSerial, (int)sizeof(tsSerial));
|
|
ExpectIntEQ(tstDec.genTimeSz, (word32)sizeof(tsGenTime) - 1);
|
|
ExpectBufEQ(tstDec.genTime, tsGenTime, (int)sizeof(tsGenTime) - 1);
|
|
|
|
/* Round trip the tsa field. */
|
|
tst.tsa = tsTsaName;
|
|
tst.tsaSz = (word32)sizeof(tsTsaName);
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, enc, sz), 0);
|
|
ExpectIntEQ(tstDec.tsaSz, (word32)sizeof(tsTsaName));
|
|
ExpectBufEQ(tstDec.tsa, tsTsaName, (int)sizeof(tsTsaName));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_CheckGenTime(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && !defined(NO_SHA256) && !defined(NO_ASN_TIME) && \
|
|
!defined(USER_TIME) && !defined(TIME_OVERRIDES) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
TspTstInfo tst;
|
|
TspTstInfo tstDec;
|
|
byte enc[256];
|
|
word32 sz = (word32)sizeof(enc);
|
|
|
|
/* TSTInfo with the current time. */
|
|
test_tsp_set_tstinfo(&tst);
|
|
tst.genTime = NULL;
|
|
tst.genTimeSz = 0;
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_Decode(&tstDec, enc, sz), 0);
|
|
|
|
/* Bad arguments. */
|
|
ExpectIntEQ(wc_TspTstInfo_CheckGenTime(NULL, 10),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_CheckGenTime(&tst, 10),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* The current time is within tolerance. */
|
|
ExpectIntEQ(wc_TspTstInfo_CheckGenTime(&tstDec, 10), 0);
|
|
|
|
/* A time in the past is not. */
|
|
tst.genTime = (const byte*)"19700101000000Z";
|
|
tst.genTimeSz = 15;
|
|
ExpectIntEQ(wc_TspTstInfo_CheckGenTime(&tst, 60),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
/* A time in the future is not. */
|
|
tst.genTime = (const byte*)"20990101000000Z";
|
|
ExpectIntEQ(wc_TspTstInfo_CheckGenTime(&tst, 60),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
/* An invalid time string. */
|
|
tst.genTimeSz = 14;
|
|
ExpectIntEQ(wc_TspTstInfo_CheckGenTime(&tst, 60),
|
|
WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_GetSetGenTimeAsTime(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && !defined(NO_ASN_TIME) && \
|
|
defined(WOLFSSL_TSP_VERIFIER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
TspTstInfo tst;
|
|
byte buf[ASN_GENERALIZED_TIME_SIZE];
|
|
const byte* out = NULL;
|
|
word32 outSz = 0;
|
|
time_t t = 0;
|
|
|
|
ExpectIntEQ(wc_TspTstInfo_Init(&tst), 0);
|
|
|
|
/* Set: bad arguments. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetGenTimeAsTime(NULL, 0, buf,
|
|
(word32)sizeof(buf)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetGenTimeAsTime(&tst, 0, NULL,
|
|
(word32)sizeof(buf)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Buffer too small for the GeneralizedTime string. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetGenTimeAsTime(&tst, 0, buf,
|
|
ASN_GENERALIZED_TIME_SIZE - 1), WC_NO_ERR_TRACE(BUFFER_E));
|
|
|
|
/* The Unix epoch formats as a known GeneralizedTime and references buf. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetGenTimeAsTime(&tst, 0, buf,
|
|
(word32)sizeof(buf)), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTime(&tst, &out, &outSz), 0);
|
|
ExpectPtrEq(out, buf);
|
|
ExpectIntEQ(outSz, 15);
|
|
ExpectBufEQ(out, "19700101000000Z", 15);
|
|
/* Get round trips back to the time_t. */
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t), 0);
|
|
ExpectIntEQ((long)t, 0);
|
|
|
|
/* A later time round trips through set then get. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetGenTimeAsTime(&tst, (time_t)1700000000, buf,
|
|
(word32)sizeof(buf)), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t), 0);
|
|
ExpectIntEQ((long)t, 1700000000L);
|
|
|
|
/* Get ignores a fraction of a second. */
|
|
tst.genTime = (const byte*)"19700101000000.5Z";
|
|
tst.genTimeSz = 17;
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t), 0);
|
|
ExpectIntEQ((long)t, 0);
|
|
|
|
/* Get: bad arguments. */
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(NULL, &t),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Get: an invalid time string. */
|
|
tst.genTime = (const byte*)"19700101000000";
|
|
tst.genTimeSz = 14;
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t),
|
|
WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
/* Get: out-of-range fields are rejected, not used to index a table.
|
|
* A month of 00 or 13-99 would otherwise read outside the month table. */
|
|
tst.genTime = (const byte*)"19700001000000Z"; /* month 00 */
|
|
tst.genTimeSz = 15;
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t),
|
|
WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
tst.genTime = (const byte*)"19701301000000Z"; /* month 13 */
|
|
tst.genTimeSz = 15;
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t),
|
|
WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
tst.genTime = (const byte*)"19709901000000Z"; /* month 99 */
|
|
tst.genTimeSz = 15;
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t),
|
|
WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
tst.genTime = (const byte*)"19700100000000Z"; /* day 00 */
|
|
tst.genTimeSz = 15;
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t),
|
|
WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
tst.genTime = (const byte*)"19700101240000Z"; /* hour 24 */
|
|
tst.genTimeSz = 15;
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t),
|
|
WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
tst.genTime = (const byte*)"19700101006000Z"; /* minute 60 */
|
|
tst.genTimeSz = 15;
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t),
|
|
WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
tst.genTime = (const byte*)"19700101000061Z"; /* second 61 */
|
|
tst.genTimeSz = 15;
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t),
|
|
WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
/* A leap second (60) is accepted. */
|
|
tst.genTime = (const byte*)"19700101000060Z";
|
|
tst.genTimeSz = 15;
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t), 0);
|
|
/* Get: no time present. */
|
|
tst.genTime = NULL;
|
|
tst.genTimeSz = 0;
|
|
ExpectIntEQ(wc_TspTstInfo_GetGenTimeAsTime(&tst, &t),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspResponse_Init(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && \
|
|
defined(WOLFSSL_TSP_RESPONDER)
|
|
TspResponse resp;
|
|
|
|
ExpectIntEQ(wc_TspResponse_Init(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Setting the status of a NULL response is rejected. */
|
|
ExpectIntEQ(wc_TspResponse_SetStatus(NULL, WC_TSP_PKISTATUS_GRANTED, NULL,
|
|
0, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
XMEMSET(&resp, 0xa5, sizeof(TspResponse));
|
|
ExpectIntEQ(wc_TspResponse_Init(&resp), 0);
|
|
ExpectIntEQ(resp.status, WC_TSP_PKISTATUS_GRANTED);
|
|
ExpectNull(resp.statusString);
|
|
ExpectIntEQ(resp.failInfo, 0);
|
|
ExpectNull(resp.token);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspGetSetStatus(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
static const char statusText[] = "rejected by policy";
|
|
TspResponse resp;
|
|
word32 status = 0;
|
|
const byte* str = NULL;
|
|
word32 strSz = 0;
|
|
word32 failInfo = 0;
|
|
|
|
ExpectIntEQ(wc_TspResponse_Init(&resp), 0);
|
|
|
|
/* Bad arguments - NULL response. */
|
|
ExpectIntEQ(wc_TspResponse_GetStatus(NULL, &status, &str, &strSz,
|
|
&failInfo), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspResponse_SetStatus(NULL, WC_TSP_PKISTATUS_GRANTED, NULL,
|
|
0, 0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* Set status, string and failure information - string is assigned. */
|
|
ExpectIntEQ(wc_TspResponse_SetStatus(&resp, WC_TSP_PKISTATUS_REJECTION,
|
|
(const byte*)statusText, (word32)XSTRLEN(statusText),
|
|
WC_TSP_FAIL_BAD_ALG | WC_TSP_FAIL_SYSTEM_FAILURE), 0);
|
|
if (EXPECT_SUCCESS()) {
|
|
ExpectIntEQ(resp.status, WC_TSP_PKISTATUS_REJECTION);
|
|
ExpectPtrEq(resp.statusString, statusText);
|
|
ExpectIntEQ(resp.statusStringSz, (word32)XSTRLEN(statusText));
|
|
ExpectIntEQ(resp.failInfo,
|
|
WC_TSP_FAIL_BAD_ALG | WC_TSP_FAIL_SYSTEM_FAILURE);
|
|
}
|
|
|
|
/* Get returns each value asked for. */
|
|
ExpectIntEQ(wc_TspResponse_GetStatus(&resp, &status, &str, &strSz,
|
|
&failInfo), 0);
|
|
if (EXPECT_SUCCESS()) {
|
|
ExpectIntEQ(status, WC_TSP_PKISTATUS_REJECTION);
|
|
ExpectPtrEq(str, statusText);
|
|
ExpectIntEQ(strSz, (word32)XSTRLEN(statusText));
|
|
ExpectIntEQ(failInfo, WC_TSP_FAIL_BAD_ALG | WC_TSP_FAIL_SYSTEM_FAILURE);
|
|
}
|
|
|
|
/* All outputs are optional - NULLs retrieve nothing. */
|
|
ExpectIntEQ(wc_TspResponse_GetStatus(&resp, NULL, NULL, NULL, NULL), 0);
|
|
|
|
/* A NULL string clears the string and its length. */
|
|
ExpectIntEQ(wc_TspResponse_SetStatus(&resp, WC_TSP_PKISTATUS_GRANTED, NULL,
|
|
5, 0), 0);
|
|
str = (const byte*)statusText;
|
|
strSz = 99;
|
|
ExpectIntEQ(wc_TspResponse_GetStatus(&resp, &status, &str, &strSz,
|
|
&failInfo), 0);
|
|
if (EXPECT_SUCCESS()) {
|
|
ExpectIntEQ(status, WC_TSP_PKISTATUS_GRANTED);
|
|
ExpectNull(str);
|
|
ExpectIntEQ(strSz, 0);
|
|
ExpectIntEQ(failInfo, 0);
|
|
}
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspStrings(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#ifdef WOLFSSL_TSP
|
|
/* Each PKIStatus has a description. */
|
|
ExpectStrEQ(wc_TspStatus_ToString(WC_TSP_PKISTATUS_GRANTED), "granted");
|
|
ExpectStrEQ(wc_TspStatus_ToString(WC_TSP_PKISTATUS_REJECTION), "rejection");
|
|
ExpectNotNull(wc_TspStatus_ToString(WC_TSP_PKISTATUS_GRANTED_WITH_MODS));
|
|
ExpectNotNull(wc_TspStatus_ToString(WC_TSP_PKISTATUS_WAITING));
|
|
ExpectNotNull(wc_TspStatus_ToString(WC_TSP_PKISTATUS_REVOCATION_WARNING));
|
|
ExpectNotNull(wc_TspStatus_ToString(
|
|
WC_TSP_PKISTATUS_REVOCATION_NOTIFICATION));
|
|
/* An unknown status still returns a string. */
|
|
ExpectStrEQ(wc_TspStatus_ToString(99), "unknown status");
|
|
|
|
/* Each PKIFailureInfo flag has a description. */
|
|
ExpectStrEQ(wc_TspFailInfo_ToString(WC_TSP_FAIL_SYSTEM_FAILURE),
|
|
"the request cannot be handled due to system failure");
|
|
ExpectNotNull(wc_TspFailInfo_ToString(WC_TSP_FAIL_BAD_ALG));
|
|
ExpectNotNull(wc_TspFailInfo_ToString(WC_TSP_FAIL_BAD_REQUEST));
|
|
ExpectNotNull(wc_TspFailInfo_ToString(WC_TSP_FAIL_BAD_DATA_FORMAT));
|
|
ExpectNotNull(wc_TspFailInfo_ToString(WC_TSP_FAIL_TIME_NOT_AVAILABLE));
|
|
ExpectNotNull(wc_TspFailInfo_ToString(WC_TSP_FAIL_UNACCEPTED_POLICY));
|
|
ExpectNotNull(wc_TspFailInfo_ToString(WC_TSP_FAIL_UNACCEPTED_EXTENSION));
|
|
ExpectNotNull(wc_TspFailInfo_ToString(WC_TSP_FAIL_ADD_INFO_NOT_AVAILABLE));
|
|
/* An unknown or empty failure information still returns a string. */
|
|
ExpectStrEQ(wc_TspFailInfo_ToString(0), "unknown failure information");
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspResponse_Encode(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* All failure information flags. RFC 3161, 2.4.2. */
|
|
static const word32 failInfoFlags[] = {
|
|
WC_TSP_FAIL_BAD_ALG,
|
|
WC_TSP_FAIL_BAD_REQUEST,
|
|
WC_TSP_FAIL_BAD_DATA_FORMAT,
|
|
WC_TSP_FAIL_TIME_NOT_AVAILABLE,
|
|
WC_TSP_FAIL_UNACCEPTED_POLICY,
|
|
WC_TSP_FAIL_UNACCEPTED_EXTENSION,
|
|
WC_TSP_FAIL_ADD_INFO_NOT_AVAILABLE,
|
|
WC_TSP_FAIL_SYSTEM_FAILURE
|
|
};
|
|
/* Stand-in for a token - decoded as opaque DER. */
|
|
static const byte token[] = { 0x30, 0x03, 0x02, 0x01, 0x05 };
|
|
static const char statusText[] = "rejected by policy";
|
|
TspResponse resp;
|
|
TspResponse respDec;
|
|
byte enc[256];
|
|
word32 encSz;
|
|
word32 sz;
|
|
word32 i;
|
|
|
|
ExpectIntEQ(wc_TspResponse_Init(&resp), 0);
|
|
|
|
/* Bad arguments. */
|
|
encSz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspResponse_Encode(NULL, enc, &encSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspResponse_Encode(&resp, enc, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* Smallest response. */
|
|
encSz = 0;
|
|
ExpectIntEQ(wc_TspResponse_Encode(&resp, NULL, &encSz), 0);
|
|
ExpectIntGT(encSz, 0);
|
|
/* Buffer too small. */
|
|
sz = encSz - 1;
|
|
ExpectIntEQ(wc_TspResponse_Encode(&resp, enc, &sz),
|
|
WC_NO_ERR_TRACE(BUFFER_E));
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspResponse_Encode(&resp, enc, &sz), 0);
|
|
ExpectIntEQ(sz, encSz);
|
|
ExpectIntEQ(wc_TspResponse_Decode(&respDec, enc, sz), 0);
|
|
ExpectIntEQ(respDec.status, WC_TSP_PKISTATUS_GRANTED);
|
|
ExpectNull(respDec.statusString);
|
|
ExpectIntEQ(respDec.failInfo, 0);
|
|
ExpectNull(respDec.token);
|
|
|
|
/* Rejection with status string and each failure information flag. */
|
|
resp.status = WC_TSP_PKISTATUS_REJECTION;
|
|
resp.statusString = (const byte*)statusText;
|
|
resp.statusStringSz = (word32)XSTRLEN(statusText);
|
|
for (i = 0; i < (word32)(sizeof(failInfoFlags) / sizeof(*failInfoFlags));
|
|
i++) {
|
|
resp.failInfo = failInfoFlags[i];
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspResponse_Encode(&resp, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspResponse_Decode(&respDec, enc, sz), 0);
|
|
ExpectIntEQ(respDec.status, WC_TSP_PKISTATUS_REJECTION);
|
|
ExpectIntEQ(respDec.failInfo, failInfoFlags[i]);
|
|
ExpectIntEQ(respDec.statusStringSz, (word32)XSTRLEN(statusText));
|
|
ExpectBufEQ(respDec.statusString, statusText,
|
|
(int)XSTRLEN(statusText));
|
|
}
|
|
/* Multiple failure information flags. */
|
|
resp.failInfo = WC_TSP_FAIL_BAD_ALG | WC_TSP_FAIL_BAD_REQUEST;
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspResponse_Encode(&resp, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspResponse_Decode(&respDec, enc, sz), 0);
|
|
ExpectIntEQ(respDec.failInfo,
|
|
WC_TSP_FAIL_BAD_ALG | WC_TSP_FAIL_BAD_REQUEST);
|
|
|
|
/* Granted with a token. */
|
|
ExpectIntEQ(wc_TspResponse_Init(&resp), 0);
|
|
resp.token = token;
|
|
resp.tokenSz = (word32)sizeof(token);
|
|
sz = (word32)sizeof(enc);
|
|
ExpectIntEQ(wc_TspResponse_Encode(&resp, enc, &sz), 0);
|
|
ExpectIntEQ(wc_TspResponse_Decode(&respDec, enc, sz), 0);
|
|
ExpectIntEQ(respDec.status, WC_TSP_PKISTATUS_GRANTED);
|
|
ExpectIntEQ(respDec.tokenSz, (word32)sizeof(token));
|
|
ExpectBufEQ(respDec.token, token, (int)sizeof(token));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspResponse_Decode(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(WOLFSSL_TSP_VERIFIER)
|
|
/* Rejection with failure information of badRequest - OpenSSL style BIT
|
|
* STRING with unused bits. */
|
|
static const byte failInfoDer[] = {
|
|
0x30, 0x09, 0x30, 0x07,
|
|
0x02, 0x01, 0x02,
|
|
0x03, 0x02, 0x05, 0x20
|
|
};
|
|
/* Rejection with a PKIFreeText holding two strings. */
|
|
static const byte twoStrDer[] = {
|
|
0x30, 0x12, 0x30, 0x10,
|
|
0x02, 0x01, 0x02,
|
|
0x30, 0x0b,
|
|
0x0c, 0x03, 'a', 'b', 'c',
|
|
0x0c, 0x04, 'd', 'e', 'f', 'g'
|
|
};
|
|
/* Invalid: PKIFreeText must have at least one string. */
|
|
static const byte emptyStrDer[] = {
|
|
0x30, 0x07, 0x30, 0x05,
|
|
0x02, 0x01, 0x02,
|
|
0x30, 0x00
|
|
};
|
|
/* Failure information with more bits than recognized - invalid. */
|
|
static const byte longFailDer[] = {
|
|
0x30, 0x0d, 0x30, 0x0b,
|
|
0x02, 0x01, 0x02,
|
|
0x03, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80
|
|
};
|
|
/* Present but empty failInfo BIT STRING - only the unused bits byte. */
|
|
static const byte emptyFailDer[] = {
|
|
0x30, 0x08, 0x30, 0x06,
|
|
0x02, 0x01, 0x02,
|
|
0x03, 0x01, 0x00
|
|
};
|
|
TspResponse respDec;
|
|
byte enc[32];
|
|
word32 status = 0;
|
|
|
|
/* Bad arguments. */
|
|
ExpectIntEQ(wc_TspResponse_Decode(NULL, failInfoDer,
|
|
(word32)sizeof(failInfoDer)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Getting the status of a NULL response is rejected. */
|
|
ExpectIntEQ(wc_TspResponse_GetStatus(NULL, &status, NULL, NULL, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspResponse_Decode(&respDec, NULL,
|
|
(word32)sizeof(failInfoDer)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspResponse_Decode(&respDec, failInfoDer, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* Failure information with unused bits in BIT STRING. */
|
|
ExpectIntEQ(wc_TspResponse_Decode(&respDec, failInfoDer,
|
|
(word32)sizeof(failInfoDer)), 0);
|
|
ExpectIntEQ(respDec.status, WC_TSP_PKISTATUS_REJECTION);
|
|
ExpectIntEQ(respDec.failInfo, WC_TSP_FAIL_BAD_REQUEST);
|
|
ExpectNull(respDec.statusString);
|
|
ExpectNull(respDec.token);
|
|
|
|
/* First string of PKIFreeText returned. */
|
|
ExpectIntEQ(wc_TspResponse_Decode(&respDec, twoStrDer,
|
|
(word32)sizeof(twoStrDer)), 0);
|
|
ExpectIntEQ(respDec.statusStringSz, 3);
|
|
ExpectBufEQ(respDec.statusString, "abc", 3);
|
|
|
|
/* Empty PKIFreeText invalid. */
|
|
ExpectIntLT(wc_TspResponse_Decode(&respDec, emptyStrDer,
|
|
(word32)sizeof(emptyStrDer)), 0);
|
|
|
|
/* Failure information bits past 31 are not supported. */
|
|
ExpectIntEQ(wc_TspResponse_Decode(&respDec, longFailDer,
|
|
(word32)sizeof(longFailDer)), WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
|
|
/* Present but empty failInfo BIT STRING (only the unused bits byte) has no
|
|
* data bytes and is rejected - the shift over the encoded length is never
|
|
* reached, so it cannot shift a word32 by 32. */
|
|
ExpectIntEQ(wc_TspResponse_Decode(&respDec, emptyFailDer,
|
|
(word32)sizeof(emptyFailDer)), WC_NO_ERR_TRACE(ASN_PARSE_E));
|
|
|
|
/* Truncated encoding. */
|
|
ExpectIntLT(wc_TspResponse_Decode(&respDec, failInfoDer,
|
|
(word32)sizeof(failInfoDer) - 1), 0);
|
|
/* Trailing data not allowed. */
|
|
XMEMCPY(enc, failInfoDer, sizeof(failInfoDer));
|
|
enc[sizeof(failInfoDer)] = 0x00;
|
|
ExpectIntLT(wc_TspResponse_Decode(&respDec, enc,
|
|
(word32)sizeof(failInfoDer) + 1), 0);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_CheckRequest(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* Nonce with extra leading zero byte. */
|
|
static const byte paddedNonce[] = {
|
|
0x00, 0xc3, 0x5a, 0x10, 0x42, 0x77, 0x08, 0x99, 0x01
|
|
};
|
|
static const byte otherNonce[] = { 0x01, 0x02 };
|
|
/* Nonce of zero in different number of bytes. */
|
|
static const byte zeroNonce1[] = { 0x00 };
|
|
static const byte zeroNonce2[] = { 0x00, 0x00 };
|
|
TspTstInfo tst;
|
|
TspRequest req;
|
|
|
|
/* Matching request and TSTInfo - no encoding required for check. */
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
test_tsp_set_hash(&req.imprint);
|
|
XMEMCPY(req.policy, tsPolicy, sizeof(tsPolicy));
|
|
req.policySz = (word32)sizeof(tsPolicy);
|
|
XMEMCPY(req.nonce, tsNonce, sizeof(tsNonce));
|
|
req.nonceSz = (word32)sizeof(tsNonce);
|
|
ExpectIntEQ(wc_TspTstInfo_Init(&tst), 0);
|
|
tst.policy = tsPolicy;
|
|
tst.policySz = (word32)sizeof(tsPolicy);
|
|
test_tsp_set_hash(&tst.imprint);
|
|
tst.nonce = tsNonce;
|
|
tst.nonceSz = (word32)sizeof(tsNonce);
|
|
|
|
/* Bad arguments. */
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(NULL, &req),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req), 0);
|
|
|
|
/* Only version 1 supported. */
|
|
tst.version = 2;
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req),
|
|
WC_NO_ERR_TRACE(ASN_VERSION_E));
|
|
tst.version = WC_TSP_VERSION;
|
|
|
|
/* Hash algorithm different. */
|
|
tst.imprint.hashAlgOID = SHA256h + 1;
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
tst.imprint.hashAlgOID = SHA256h;
|
|
/* Hash length different. */
|
|
tst.imprint.hashSz--;
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
tst.imprint.hashSz++;
|
|
/* Hash different. */
|
|
tst.imprint.hash[0] ^= 0x80;
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
tst.imprint.hash[0] ^= 0x80;
|
|
|
|
/* Nonce in request must be in TSTInfo. */
|
|
tst.nonce = NULL;
|
|
tst.nonceSz = 0;
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
/* Nonces compared exactly - same number with leading zero byte does not
|
|
* match. */
|
|
tst.nonce = paddedNonce;
|
|
tst.nonceSz = (word32)sizeof(paddedNonce);
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
/* Request's nonce with leading zero byte. */
|
|
XMEMCPY(req.nonce, paddedNonce, sizeof(paddedNonce));
|
|
req.nonceSz = (word32)sizeof(paddedNonce);
|
|
tst.nonce = tsNonce;
|
|
tst.nonceSz = (word32)sizeof(tsNonce);
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
/* Nonce of zero with different lengths. */
|
|
XMEMCPY(req.nonce, zeroNonce2, sizeof(zeroNonce2));
|
|
req.nonceSz = (word32)sizeof(zeroNonce2);
|
|
tst.nonce = zeroNonce1;
|
|
tst.nonceSz = (word32)sizeof(zeroNonce1);
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
XMEMCPY(req.nonce, tsNonce, sizeof(tsNonce));
|
|
req.nonceSz = (word32)sizeof(tsNonce);
|
|
/* Nonce different. */
|
|
tst.nonce = otherNonce;
|
|
tst.nonceSz = (word32)sizeof(otherNonce);
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
tst.nonce = tsNonce;
|
|
tst.nonceSz = (word32)sizeof(tsNonce);
|
|
/* Nonce in TSTInfo and not request is allowed. */
|
|
req.nonceSz = 0;
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req), 0);
|
|
XMEMCPY(req.nonce, tsNonce, sizeof(tsNonce));
|
|
req.nonceSz = (word32)sizeof(tsNonce);
|
|
|
|
/* Policy in request must be in TSTInfo. */
|
|
tst.policy = NULL;
|
|
tst.policySz = 0;
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
/* Policy different. */
|
|
tst.policy = tsNonce;
|
|
tst.policySz = (word32)sizeof(tsNonce);
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
tst.policy = tsPolicy;
|
|
tst.policySz = (word32)sizeof(tsPolicy);
|
|
/* Policy not checked when not requested. */
|
|
req.policySz = 0;
|
|
ExpectIntEQ(wc_TspTstInfo_CheckRequest(&tst, &req), 0);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER) && \
|
|
(!defined(NO_RSA) || defined(HAVE_ECC))
|
|
/* Create a PKCS7 object ready to sign with the certificate and key using the
|
|
* given encryption algorithm. */
|
|
static int test_tsp_new_signer_ex(wc_PKCS7** pkcs7, WC_RNG* rng,
|
|
const byte* cert, word32 certSz, const byte* key, word32 keySz,
|
|
int encryptOID)
|
|
{
|
|
EXPECT_DECLS;
|
|
|
|
ExpectNotNull(*pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(*pkcs7, (byte*)cert, certSz), 0);
|
|
if (EXPECT_SUCCESS()) {
|
|
(*pkcs7)->rng = rng;
|
|
(*pkcs7)->hashOID = SHA256h;
|
|
(*pkcs7)->encryptOID = encryptOID;
|
|
(*pkcs7)->privateKey = (byte*)key;
|
|
(*pkcs7)->privateKeySz = keySz;
|
|
}
|
|
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
#ifndef NO_RSA
|
|
/* Create a PKCS7 object ready to sign with the RSA certificate and key. */
|
|
static int test_tsp_new_signer(wc_PKCS7** pkcs7, WC_RNG* rng, const byte* cert,
|
|
word32 certSz, const byte* key, word32 keySz)
|
|
{
|
|
return test_tsp_new_signer_ex(pkcs7, rng, cert, certSz, key, keySz, RSAk);
|
|
}
|
|
|
|
/* Create a PKCS7 object ready to sign as the TSA. */
|
|
static int test_tsp_new_tsa_signer(wc_PKCS7** pkcs7, WC_RNG* rng)
|
|
{
|
|
return test_tsp_new_signer(pkcs7, rng, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048);
|
|
}
|
|
#endif /* !NO_RSA */
|
|
|
|
/* Build a standard time-stamp token signed with the given certificate and key.
|
|
* Encapsulates the signing PKCS7 so verify tests need only their own object. */
|
|
static int test_tsp_make_token(byte* token, word32* tokenSz, const byte* cert,
|
|
word32 certSz, const byte* key, word32 keySz, int encryptOID, WC_RNG* rng)
|
|
{
|
|
EXPECT_DECLS;
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
TspTstInfo tst;
|
|
|
|
test_tsp_set_tstinfo(&tst);
|
|
tst.nonce = tsNonce;
|
|
tst.nonceSz = (word32)sizeof(tsNonce);
|
|
|
|
ExpectIntEQ(test_tsp_new_signer_ex(&pkcs7, rng, cert, certSz, key, keySz,
|
|
encryptOID), TEST_SUCCESS);
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(&tst, pkcs7, token, tokenSz), 0);
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
return EXPECT_RESULT();
|
|
}
|
|
#endif
|
|
|
|
int test_wc_TspTstInfo_SignWithPkcs7(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tst;
|
|
byte token[3072];
|
|
word32 tokenSz;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
test_tsp_set_tstinfo(&tst);
|
|
tst.nonce = tsNonce;
|
|
tst.nonceSz = (word32)sizeof(tsNonce);
|
|
ExpectIntEQ(test_tsp_new_tsa_signer(&pkcs7, &rng), TEST_SUCCESS);
|
|
|
|
/* Bad arguments. */
|
|
tokenSz = (word32)sizeof(token);
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(&tst, NULL, token, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(NULL, pkcs7, token, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(&tst, pkcs7, NULL, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(&tst, pkcs7, token, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
wc_PKCS7_Free(pkcs7);
|
|
pkcs7 = NULL;
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_SignWithPkcs7_create(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
byte token[3072];
|
|
word32 tokenSz;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* Create a token and check the TSTInfo it holds. */
|
|
tokenSz = (word32)sizeof(token);
|
|
ExpectIntEQ(test_tsp_make_token(token, &tokenSz, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
RSAk, &rng), TEST_SUCCESS);
|
|
ExpectIntGT(tokenSz, 0);
|
|
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, &tstDec), 0);
|
|
ExpectIntEQ(tstDec.version, WC_TSP_VERSION);
|
|
ExpectBufEQ(tstDec.imprint.hash, tsHashedMsg,
|
|
(int)sizeof(tsHashedMsg));
|
|
ExpectIntEQ(tstDec.nonceSz, (word32)sizeof(tsNonce));
|
|
ExpectBufEQ(tstDec.nonce, tsNonce, (int)sizeof(tsNonce));
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_SignWithPkcs7_signer_required(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
TspTstInfo tst;
|
|
byte token[3072];
|
|
word32 tokenSz;
|
|
|
|
test_tsp_set_tstinfo(&tst);
|
|
tst.nonce = tsNonce;
|
|
tst.nonceSz = (word32)sizeof(tsNonce);
|
|
|
|
/* Signer's certificate required. */
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
tokenSz = (word32)sizeof(token);
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(&tst, pkcs7, token, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
wc_PKCS7_Free(pkcs7);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_SignWithPkcs7_hash_and_buffer(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tst;
|
|
byte token[3072];
|
|
word32 tokenSz;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
test_tsp_set_tstinfo(&tst);
|
|
tst.nonce = tsNonce;
|
|
tst.nonceSz = (word32)sizeof(tsNonce);
|
|
|
|
/* Hash algorithm of PKCS7 object must be usable. */
|
|
ExpectIntEQ(test_tsp_new_tsa_signer(&pkcs7, &rng), TEST_SUCCESS);
|
|
if (EXPECT_SUCCESS()) {
|
|
pkcs7->hashOID = 0;
|
|
}
|
|
tokenSz = (word32)sizeof(token);
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(&tst, pkcs7, token, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Output buffer too small - PKCS7 object fields are put back. */
|
|
if (EXPECT_SUCCESS()) {
|
|
pkcs7->hashOID = SHA256h;
|
|
}
|
|
tokenSz = 16;
|
|
ExpectIntLT(wc_TspTstInfo_SignWithPkcs7(&tst, pkcs7, token, &tokenSz), 0);
|
|
if (EXPECT_SUCCESS()) {
|
|
ExpectNull(pkcs7->content);
|
|
ExpectIntEQ(pkcs7->contentSz, 0);
|
|
ExpectNull(pkcs7->signedAttribs);
|
|
ExpectIntEQ(pkcs7->signedAttribsSz, 0);
|
|
}
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_Sign(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
WC_RNG rng;
|
|
TspTstInfo tst;
|
|
TspTstInfo tstDec;
|
|
TspResponse resp;
|
|
byte token[3072];
|
|
word32 tokenSz;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
test_tsp_set_tstinfo(&tst);
|
|
|
|
/* Bad arguments. */
|
|
tokenSz = (word32)sizeof(token);
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(NULL, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
WC_PK_TYPE_RSA, WC_HASH_TYPE_SHA256, &rng, token, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(&tst, NULL,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
WC_PK_TYPE_RSA, WC_HASH_TYPE_SHA256, &rng, token, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(&tst, tsa_cert_der_2048, 0,
|
|
tsa_key_der_2048, sizeof_tsa_key_der_2048, WC_PK_TYPE_RSA,
|
|
WC_HASH_TYPE_SHA256, &rng, token, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(&tst, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, NULL, sizeof_tsa_key_der_2048,
|
|
WC_PK_TYPE_RSA, WC_HASH_TYPE_SHA256, &rng, token, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(&tst, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, 0, WC_PK_TYPE_RSA,
|
|
WC_HASH_TYPE_SHA256, &rng, token, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(&tst, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
WC_PK_TYPE_RSA, WC_HASH_TYPE_SHA256, NULL, token, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(&tst, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
WC_PK_TYPE_RSA, WC_HASH_TYPE_SHA256, &rng, NULL, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(&tst, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
WC_PK_TYPE_RSA, WC_HASH_TYPE_SHA256, &rng, token, NULL),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Unsupported key type. */
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(&tst, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
WC_PK_TYPE_DH, WC_HASH_TYPE_SHA256, &rng, token, &tokenSz),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
/* Hash algorithm not available. */
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(&tst, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
WC_PK_TYPE_RSA, WC_HASH_TYPE_NONE, &rng, token, &tokenSz),
|
|
WC_NO_ERR_TRACE(HASH_TYPE_E));
|
|
|
|
/* Create an RSA-signed token and verify it against the TSA certificate. */
|
|
tokenSz = (word32)sizeof(token);
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(&tst, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
WC_PK_TYPE_RSA, WC_HASH_TYPE_SHA256, &rng, token, &tokenSz), 0);
|
|
ExpectIntGT(tokenSz, 0);
|
|
ExpectIntEQ(wc_TspResponse_Init(&resp), 0);
|
|
resp.status = WC_TSP_PKISTATUS_GRANTED;
|
|
resp.token = token;
|
|
resp.tokenSz = tokenSz;
|
|
ExpectIntEQ(wc_TspResponse_Verify(&resp, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, &tstDec), 0);
|
|
ExpectIntEQ(tstDec.version, WC_TSP_VERSION);
|
|
|
|
#ifdef HAVE_ECC
|
|
/* Create an ECDSA-signed token and verify it. */
|
|
tokenSz = (word32)sizeof(token);
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(&tst, tsa_ecc_cert_der_256,
|
|
sizeof_tsa_ecc_cert_der_256, tsa_ecc_key_der_256,
|
|
sizeof_tsa_ecc_key_der_256, WC_PK_TYPE_ECDSA_SIGN,
|
|
WC_HASH_TYPE_SHA256, &rng, token, &tokenSz), 0);
|
|
ExpectIntEQ(wc_TspResponse_Init(&resp), 0);
|
|
resp.status = WC_TSP_PKISTATUS_GRANTED;
|
|
resp.token = token;
|
|
resp.tokenSz = tokenSz;
|
|
ExpectIntEQ(wc_TspResponse_Verify(&resp, tsa_ecc_cert_der_256,
|
|
sizeof_tsa_ecc_cert_der_256, &tstDec), 0);
|
|
ExpectIntEQ(tstDec.version, WC_TSP_VERSION);
|
|
#endif
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* Custom user attribute OID 1.2.5555 with a UTF8String value. */
|
|
static const byte tspCustomOid[] = { 0x06, 0x03, 0x2a, 0xab, 0x33 };
|
|
static const byte tspCustomValue[] = { 0x0c, 0x02, 'h', 'i' };
|
|
|
|
/* Sign a standard TSTInfo token that also carries the custom user attribute.
|
|
* Encapsulates the signing PKCS7 so verify tests need only their own object. */
|
|
static int test_tsp_make_attrib_token(byte* token, word32* tokenSz, WC_RNG* rng)
|
|
{
|
|
EXPECT_DECLS;
|
|
PKCS7Attrib attrib;
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
TspTstInfo tst;
|
|
|
|
XMEMSET(&attrib, 0, sizeof(attrib));
|
|
attrib.oid = tspCustomOid;
|
|
attrib.oidSz = (word32)sizeof(tspCustomOid);
|
|
attrib.value = tspCustomValue;
|
|
attrib.valueSz = (word32)sizeof(tspCustomValue);
|
|
|
|
test_tsp_set_tstinfo(&tst);
|
|
|
|
ExpectIntEQ(test_tsp_new_tsa_signer(&pkcs7, rng), TEST_SUCCESS);
|
|
if (EXPECT_SUCCESS()) {
|
|
pkcs7->signedAttribs = &attrib;
|
|
pkcs7->signedAttribsSz = 1;
|
|
}
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(&tst, pkcs7, token, tokenSz), 0);
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
#ifdef WOLFSSL_SHA384
|
|
/* Sign a standard TSTInfo token with SHA-384 so the hash algorithm is encoded
|
|
* in the SigningCertificateV2 attribute. Encapsulates the signing PKCS7. */
|
|
static int test_tsp_make_sha384_token(byte* token, word32* tokenSz, WC_RNG* rng)
|
|
{
|
|
EXPECT_DECLS;
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
TspTstInfo tst;
|
|
|
|
test_tsp_set_tstinfo(&tst);
|
|
|
|
ExpectIntEQ(test_tsp_new_tsa_signer(&pkcs7, rng), TEST_SUCCESS);
|
|
if (EXPECT_SUCCESS()) {
|
|
pkcs7->hashOID = SHA384h;
|
|
}
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(&tst, pkcs7, token, tokenSz), 0);
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
return EXPECT_RESULT();
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
int test_wc_TspTstInfo_SignWithPkcs7_attribs(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
PKCS7Attrib attrib;
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tst;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
XMEMSET(&attrib, 0, sizeof(attrib));
|
|
attrib.oid = tspCustomOid;
|
|
attrib.oidSz = (word32)sizeof(tspCustomOid);
|
|
attrib.value = tspCustomValue;
|
|
attrib.valueSz = (word32)sizeof(tspCustomValue);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
test_tsp_set_tstinfo(&tst);
|
|
|
|
/* Create a token with a user's signed attribute as well. */
|
|
ExpectIntEQ(test_tsp_new_tsa_signer(&pkcs7, &rng), TEST_SUCCESS);
|
|
if (EXPECT_SUCCESS()) {
|
|
pkcs7->signedAttribs = &attrib;
|
|
pkcs7->signedAttribsSz = 1;
|
|
}
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(&tst, pkcs7, token, &tokenSz), 0);
|
|
/* PKCS7 object's signed attributes are put back. */
|
|
if (EXPECT_SUCCESS()) {
|
|
ExpectPtrEq(pkcs7->signedAttribs, &attrib);
|
|
ExpectIntEQ(pkcs7->signedAttribsSz, 1);
|
|
}
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_SignWithPkcs7_attribs_verify(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* id-aa-signingCertificateV2: 1.2.840.113549.1.9.16.2.47. */
|
|
static const byte signCertV2Oid[] = {
|
|
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x2f
|
|
};
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
byte attrValue[128];
|
|
word32 attrValueSz;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
ExpectIntEQ(test_tsp_make_attrib_token(token, &tokenSz, &rng),
|
|
TEST_SUCCESS);
|
|
|
|
/* Both the user's attribute and SigningCertificateV2 are in token. */
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, NULL), 0);
|
|
attrValueSz = (word32)sizeof(attrValue);
|
|
ExpectIntEQ(wc_PKCS7_GetAttributeValue(pkcs7, tspCustomOid + 2,
|
|
(word32)sizeof(tspCustomOid) - 2, attrValue, &attrValueSz),
|
|
(int)sizeof(tspCustomValue));
|
|
ExpectBufEQ(attrValue, tspCustomValue, (int)sizeof(tspCustomValue));
|
|
attrValueSz = (word32)sizeof(attrValue);
|
|
ExpectIntGT(wc_PKCS7_GetAttributeValue(pkcs7, signCertV2Oid,
|
|
(word32)sizeof(signCertV2Oid), attrValue, &attrValueSz), 0);
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_SignWithPkcs7_attribs_sha384(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
#ifdef WOLFSSL_SHA384
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* Not SHA-256: hash algorithm encoded in SigningCertificateV2. */
|
|
ExpectIntEQ(test_tsp_make_sha384_token(token, &tokenSz, &rng),
|
|
TEST_SUCCESS);
|
|
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, NULL), 0);
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* Encode a CMS SignedData with DATA content - not a time-stamp token.
|
|
* Encapsulates the signing PKCS7 so verify tests need only their own object. */
|
|
static int test_tsp_make_data_token(byte* token, word32* tokenSz, WC_RNG* rng)
|
|
{
|
|
EXPECT_DECLS;
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
byte data[] = { 0x01, 0x02, 0x03, 0x04 };
|
|
int sz = 0;
|
|
|
|
ExpectIntEQ(test_tsp_new_tsa_signer(&pkcs7, rng), TEST_SUCCESS);
|
|
if (EXPECT_SUCCESS()) {
|
|
pkcs7->content = data;
|
|
pkcs7->contentSz = (word32)sizeof(data);
|
|
pkcs7->contentOID = DATA;
|
|
}
|
|
ExpectIntGT(sz = wc_PKCS7_EncodeSignedData(pkcs7, token, *tokenSz), 0);
|
|
if (EXPECT_SUCCESS()) {
|
|
*tokenSz = (word32)sz;
|
|
}
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
/* Build a standard time-stamp token that does not include any certificates.
|
|
* Encapsulates the signing PKCS7 so verify tests need only their own object. */
|
|
static int test_tsp_make_nocerts_token(byte* token, word32* tokenSz,
|
|
WC_RNG* rng)
|
|
{
|
|
EXPECT_DECLS;
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
TspTstInfo tst;
|
|
|
|
test_tsp_set_tstinfo(&tst);
|
|
|
|
ExpectIntEQ(test_tsp_new_tsa_signer(&pkcs7, rng), TEST_SUCCESS);
|
|
if (EXPECT_SUCCESS()) {
|
|
/* Do not include certificates in the token. */
|
|
pkcs7->noCerts = 1;
|
|
}
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(&tst, pkcs7, token, tokenSz), 0);
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
return EXPECT_RESULT();
|
|
}
|
|
#endif
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
ExpectIntEQ(test_tsp_make_token(token, &tokenSz, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
RSAk, &rng), TEST_SUCCESS);
|
|
|
|
/* Bad arguments. */
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(NULL, token, tokenSz, &tstDec),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, NULL, tokenSz, &tstDec),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, 0, &tstDec),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* TSTInfo object is optional. */
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, NULL), 0);
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_modified(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
ExpectIntEQ(test_tsp_make_token(token, &tokenSz, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
RSAk, &rng), TEST_SUCCESS);
|
|
|
|
/* Modified token does not verify. */
|
|
token[tokenSz - 5] ^= 0x80;
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntLT(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, &tstDec), 0);
|
|
token[tokenSz - 5] ^= 0x80;
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_no_signer(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* Token without a SignerInfo does not verify. */
|
|
static const byte noSignerToken[] = {
|
|
0x30, 0x25, /* ContentInfo */
|
|
0x06, 0x09, /* signedData */
|
|
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02,
|
|
0xa0, 0x18, /* content */
|
|
0x30, 0x16, /* SignedData */
|
|
0x02, 0x01, 0x03, /* version 3 */
|
|
0x31, 0x00, /* digestAlgs */
|
|
0x30, 0x0d, /* encapContent */
|
|
0x06, 0x0b, /* id-ct-TSTInfo */
|
|
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04,
|
|
0x31, 0x00 /* signerInfos */
|
|
};
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
TspTstInfo tstDec;
|
|
byte noSigner[sizeof(noSignerToken)];
|
|
|
|
XMEMCPY(noSigner, noSignerToken, sizeof(noSignerToken));
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, noSigner,
|
|
(word32)sizeof(noSigner), &tstDec),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
wc_PKCS7_Free(pkcs7);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_not_tst(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* CMS SignedData that is not a time-stamp token. */
|
|
ExpectIntEQ(test_tsp_make_data_token(token, &tokenSz, &rng), TEST_SUCCESS);
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, &tstDec),
|
|
WC_NO_ERR_TRACE(PKCS7_OID_E));
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_bad_eku(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* Token signed with a certificate not for time-stamping. */
|
|
ExpectIntEQ(test_tsp_make_token(token, &tokenSz, client_cert_der_2048,
|
|
sizeof_client_cert_der_2048, client_key_der_2048,
|
|
sizeof_client_key_der_2048, RSAk, &rng), TEST_SUCCESS);
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, &tstDec),
|
|
WC_NO_ERR_TRACE(EXTKEYUSAGE_E));
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_bad_ku(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* Token signed with a time-stamping certificate with a key usage that
|
|
* is not signing. */
|
|
ExpectIntEQ(test_tsp_make_token(token, &tokenSz, tsa_bad_ku_cert_der_2048,
|
|
sizeof_tsa_bad_ku_cert_der_2048, tsa_key_der_2048,
|
|
sizeof_tsa_key_der_2048, RSAk, &rng), TEST_SUCCESS);
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, &tstDec),
|
|
WC_NO_ERR_TRACE(KEYUSAGE_E));
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_extra_eku(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* Token signed with a time-stamping certificate that has an extra
|
|
* extended key usage - the extra purpose is an unrecognized OID so the
|
|
* time-stamping bit is still the only one set, but it is not the sole
|
|
* KeyPurposeId, so verification must reject it. */
|
|
ExpectIntEQ(test_tsp_make_token(token, &tokenSz, tsa_extra_eku_cert_der_2048,
|
|
sizeof_tsa_extra_eku_cert_der_2048, tsa_key_der_2048,
|
|
sizeof_tsa_key_der_2048, RSAk, &rng), TEST_SUCCESS);
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, &tstDec),
|
|
WC_NO_ERR_TRACE(EXTKEYUSAGE_E));
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_nocerts(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* Token without certificates - certReq was FALSE in the request. */
|
|
ExpectIntEQ(test_tsp_make_nocerts_token(token, &tokenSz, &rng),
|
|
TEST_SUCCESS);
|
|
/* Cannot verify without the TSA's certificate. */
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntLT(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, &tstDec), 0);
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_nocerts_supplied(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* Token without certificates - certReq was FALSE in the request. */
|
|
ExpectIntEQ(test_tsp_make_nocerts_token(token, &tokenSz, &rng),
|
|
TEST_SUCCESS);
|
|
/* Verifies when the TSA's certificate is supplied. */
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, (byte*)tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, &tstDec), 0);
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
/* Standard verify gate for the TspResponse_Verify split. */
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* Build a token that includes the TSA's certificate and wrap it in a granted
|
|
* response. The signing PKCS7 is created and freed in the helper. */
|
|
static int test_tsp_make_granted_resp(TspResponse* resp, byte* token,
|
|
word32* tokenSz, WC_RNG* rng)
|
|
{
|
|
EXPECT_DECLS;
|
|
|
|
ExpectIntEQ(test_tsp_make_token(token, tokenSz, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
RSAk, rng), TEST_SUCCESS);
|
|
ExpectIntEQ(wc_TspResponse_Init(resp), 0);
|
|
if (EXPECT_SUCCESS()) {
|
|
resp->status = WC_TSP_PKISTATUS_GRANTED;
|
|
resp->token = token;
|
|
resp->tokenSz = *tokenSz;
|
|
}
|
|
|
|
return EXPECT_RESULT();
|
|
}
|
|
#endif
|
|
|
|
int test_wc_TspResponse_Verify(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
TspResponse resp;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
ExpectIntEQ(test_tsp_make_granted_resp(&resp, token, &tokenSz, &rng),
|
|
TEST_SUCCESS);
|
|
|
|
/* Bad arguments. */
|
|
ExpectIntEQ(wc_TspResponse_Verify(NULL, NULL, 0, &tstDec),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* Verifies with the certificate in the token - no certificate needed.
|
|
* The returned TSTInfo references the response's token, which is still
|
|
* available after the call. */
|
|
ExpectIntEQ(wc_TspResponse_Verify(&resp, NULL, 0, &tstDec), 0);
|
|
ExpectIntEQ(tstDec.version, 1);
|
|
ExpectIntEQ(tstDec.genTimeSz, (word32)sizeof(tsGenTime) - 1);
|
|
ExpectBufEQ(tstDec.genTime, tsGenTime, (int)sizeof(tsGenTime) - 1);
|
|
ExpectIntEQ(tstDec.serialSz, (word32)sizeof(tsSerial));
|
|
ExpectBufEQ(tstDec.serial, tsSerial, (int)sizeof(tsSerial));
|
|
/* The TSTInfo object is optional. */
|
|
ExpectIntEQ(wc_TspResponse_Verify(&resp, NULL, 0, NULL), 0);
|
|
|
|
/* The signer matches the trusted TSA certificate. */
|
|
ExpectIntEQ(wc_TspResponse_Verify(&resp, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, &tstDec), 0);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspResponse_Verify_wrong_cert(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
TspResponse resp;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
ExpectIntEQ(test_tsp_make_granted_resp(&resp, token, &tokenSz, &rng),
|
|
TEST_SUCCESS);
|
|
|
|
/* A different trusted certificate is not the signer - the token is signed
|
|
* by the TSA but not the one trusted. This certificate is a different
|
|
* length to the signer's. */
|
|
ExpectIntEQ(wc_TspResponse_Verify(&resp, client_cert_der_2048,
|
|
sizeof_client_cert_der_2048, &tstDec),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
/* A certificate of the same length as the signer's but with a different
|
|
* public key - the trust check is a byte comparison, not just length. */
|
|
{
|
|
byte badCert[sizeof_tsa_cert_der_2048];
|
|
|
|
XMEMCPY(badCert, tsa_cert_der_2048, sizeof(badCert));
|
|
/* Corrupt a byte of the public key. */
|
|
badCert[500] ^= 0xff;
|
|
ExpectIntEQ(wc_TspResponse_Verify(&resp, badCert,
|
|
(word32)sizeof(badCert), &tstDec), WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
}
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspResponse_Verify_status(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
TspResponse resp;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
ExpectIntEQ(test_tsp_make_granted_resp(&resp, token, &tokenSz, &rng),
|
|
TEST_SUCCESS);
|
|
|
|
/* A response that was not granted has no token to trust. */
|
|
resp.status = WC_TSP_PKISTATUS_REJECTION;
|
|
ExpectIntEQ(wc_TspResponse_Verify(&resp, NULL, 0, &tstDec),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
resp.status = WC_TSP_PKISTATUS_GRANTED_WITH_MODS;
|
|
ExpectIntEQ(wc_TspResponse_Verify(&resp, NULL, 0, &tstDec), 0);
|
|
|
|
/* A granted response with no token does not verify. */
|
|
resp.status = WC_TSP_PKISTATUS_GRANTED;
|
|
resp.token = NULL;
|
|
resp.tokenSz = 0;
|
|
ExpectIntEQ(wc_TspResponse_Verify(&resp, NULL, 0, &tstDec),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspResponse_Verify_modified(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
TspResponse resp;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
ExpectIntEQ(test_tsp_make_granted_resp(&resp, token, &tokenSz, &rng),
|
|
TEST_SUCCESS);
|
|
|
|
/* A modified token does not verify. */
|
|
if (EXPECT_SUCCESS()) {
|
|
token[tokenSz - 5] ^= 0x80;
|
|
}
|
|
ExpectIntLT(wc_TspResponse_Verify(&resp, NULL, 0, &tstDec), 0);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspResponse_Verify_nocerts(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
TspResponse resp;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
/* Token without certificates - certReq was FALSE in the request. */
|
|
ExpectIntEQ(test_tsp_make_nocerts_token(token, &tokenSz, &rng),
|
|
TEST_SUCCESS);
|
|
ExpectIntEQ(wc_TspResponse_Init(&resp), 0);
|
|
resp.status = WC_TSP_PKISTATUS_GRANTED;
|
|
resp.token = token;
|
|
resp.tokenSz = tokenSz;
|
|
|
|
/* Cannot verify without the TSA's certificate. */
|
|
ExpectIntLT(wc_TspResponse_Verify(&resp, NULL, 0, &tstDec), 0);
|
|
/* Verifies when the TSA's certificate is supplied. */
|
|
ExpectIntEQ(wc_TspResponse_Verify(&resp, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, &tstDec), 0);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspResponse_VerifyData(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tst;
|
|
TspTstInfo tstDec;
|
|
TspResponse resp;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
static const byte data[] = "wolfSSL RFC 3161 time-stamp data";
|
|
byte dataHash[WC_SHA256_DIGEST_SIZE];
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
/* The hash of the data is the token's message imprint. */
|
|
ExpectIntEQ(wc_Sha256Hash(data, (word32)sizeof(data) - 1, dataHash), 0);
|
|
|
|
test_tsp_set_tstinfo(&tst);
|
|
tst.imprint.hashAlgOID = SHA256h;
|
|
XMEMCPY(tst.imprint.hash, dataHash, sizeof(dataHash));
|
|
tst.imprint.hashSz = (word32)sizeof(dataHash);
|
|
|
|
/* A token signed by the TSA over the hash of the data. */
|
|
ExpectIntEQ(test_tsp_new_tsa_signer(&pkcs7, &rng), TEST_SUCCESS);
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(&tst, pkcs7, token, &tokenSz), 0);
|
|
wc_PKCS7_Free(pkcs7);
|
|
pkcs7 = NULL;
|
|
|
|
ExpectIntEQ(wc_TspResponse_Init(&resp), 0);
|
|
resp.status = WC_TSP_PKISTATUS_GRANTED;
|
|
resp.token = token;
|
|
resp.tokenSz = tokenSz;
|
|
|
|
/* Bad arguments. */
|
|
ExpectIntEQ(wc_TspResponse_VerifyData(NULL, NULL, 0, data,
|
|
(word32)sizeof(data) - 1, &tstDec), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspResponse_VerifyData(&resp, NULL, 0, NULL, 0, &tstDec),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* Verifies the token and that it is over the data - no hashing by the
|
|
* caller. */
|
|
ExpectIntEQ(wc_TspResponse_VerifyData(&resp, NULL, 0, data,
|
|
(word32)sizeof(data) - 1, &tstDec), 0);
|
|
ExpectIntEQ(tstDec.imprint.hashSz, (word32)sizeof(dataHash));
|
|
/* The TSTInfo object is optional. */
|
|
ExpectIntEQ(wc_TspResponse_VerifyData(&resp, NULL, 0, data,
|
|
(word32)sizeof(data) - 1, NULL), 0);
|
|
|
|
/* Different data does not match the message imprint. */
|
|
ExpectIntEQ(wc_TspResponse_VerifyData(&resp, NULL, 0,
|
|
(const byte*)"different data", 14, &tstDec),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
|
|
/* wc_TspTstInfo_VerifyData directly - bad args and match/mismatch. */
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyData(NULL, data, (word32)sizeof(data) - 1),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyData(&tstDec, NULL, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyData(&tstDec, data,
|
|
(word32)sizeof(data) - 1), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyData(&tstDec, (const byte*)"x", 1),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
/* An unknown imprint hash algorithm cannot be used to hash the data. */
|
|
{
|
|
TspTstInfo tstBad = tstDec;
|
|
|
|
tstBad.imprint.hashAlgOID = 0; /* not a known hash OID */
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyData(&tstBad, data,
|
|
(word32)sizeof(data) - 1), WC_NO_ERR_TRACE(HASH_TYPE_E));
|
|
/* An imprint length that doesn't match the algorithm's digest. */
|
|
tstBad = tstDec;
|
|
tstBad.imprint.hashSz = 16; /* SHA-256 is 32 bytes */
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyData(&tstBad, data,
|
|
(word32)sizeof(data) - 1), WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
}
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_SetFromRequest(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
WC_RNG rng;
|
|
TspRequest req;
|
|
TspRequest reqDec;
|
|
TspTstInfo tst;
|
|
TspResponse resp;
|
|
TspResponse respDec;
|
|
TspTstInfo tstDec;
|
|
byte reqDer[256];
|
|
word32 reqDerSz = (word32)sizeof(reqDer);
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
byte respDer[3072];
|
|
word32 respDerSz = (word32)sizeof(respDer);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* Requester: build and encode a request with an imprint and a nonce. */
|
|
ExpectIntEQ(wc_TspRequest_Init(&req), 0);
|
|
test_tsp_set_hash(&req.imprint);
|
|
XMEMCPY(req.nonce, tsNonce, sizeof(tsNonce));
|
|
req.nonceSz = (word32)sizeof(tsNonce);
|
|
ExpectIntEQ(wc_TspRequest_Encode(&req, reqDer, &reqDerSz), 0);
|
|
|
|
/* TSA: decode the request. */
|
|
ExpectIntEQ(wc_TspRequest_Decode(&reqDec, reqDer, reqDerSz), 0);
|
|
|
|
ExpectIntEQ(wc_TspTstInfo_Init(&tst), 0);
|
|
|
|
/* Bad arguments. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetFromRequest(NULL, &reqDec, tsPolicy,
|
|
(word32)sizeof(tsPolicy), tsSerial, (word32)sizeof(tsSerial), tsGenTime,
|
|
(word32)sizeof(tsGenTime) - 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetFromRequest(&tst, NULL, tsPolicy,
|
|
(word32)sizeof(tsPolicy), tsSerial, (word32)sizeof(tsSerial), tsGenTime,
|
|
(word32)sizeof(tsGenTime) - 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetFromRequest(&tst, &reqDec, NULL, 0, tsSerial,
|
|
(word32)sizeof(tsSerial), tsGenTime, (word32)sizeof(tsGenTime) - 1),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_SetFromRequest(&tst, &reqDec, tsPolicy,
|
|
(word32)sizeof(tsPolicy), NULL, 0, tsGenTime,
|
|
(word32)sizeof(tsGenTime) - 1), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* Set the TSTInfo from the request and the TSA's values - the request's
|
|
* message imprint and nonce are echoed. */
|
|
ExpectIntEQ(wc_TspTstInfo_SetFromRequest(&tst, &reqDec, tsPolicy,
|
|
(word32)sizeof(tsPolicy), tsSerial, (word32)sizeof(tsSerial), tsGenTime,
|
|
(word32)sizeof(tsGenTime) - 1), 0);
|
|
ExpectIntEQ(tst.imprint.hashSz, (word32)sizeof(tsHashedMsg));
|
|
ExpectBufEQ(tst.imprint.hash, tsHashedMsg, (int)sizeof(tsHashedMsg));
|
|
ExpectIntEQ(tst.nonceSz, (word32)sizeof(tsNonce));
|
|
ExpectIntEQ(tst.policySz, (word32)sizeof(tsPolicy));
|
|
ExpectIntEQ(tst.serialSz, (word32)sizeof(tsSerial));
|
|
ExpectIntEQ(tst.genTimeSz, (word32)sizeof(tsGenTime) - 1);
|
|
|
|
/* Sign the TSTInfo and wrap it in a granted response. */
|
|
ExpectIntEQ(wc_TspTstInfo_Sign(&tst, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, tsa_key_der_2048, sizeof_tsa_key_der_2048,
|
|
WC_PK_TYPE_RSA, WC_HASH_TYPE_SHA256, &rng, token, &tokenSz), 0);
|
|
ExpectIntEQ(wc_TspResponse_Init(&resp), 0);
|
|
resp.status = WC_TSP_PKISTATUS_GRANTED;
|
|
resp.token = token;
|
|
resp.tokenSz = tokenSz;
|
|
ExpectIntEQ(wc_TspResponse_Encode(&resp, respDer, &respDerSz), 0);
|
|
|
|
/* The response verifies and echoes the request's imprint and nonce. */
|
|
ExpectIntEQ(wc_TspResponse_Decode(&respDec, respDer, respDerSz), 0);
|
|
ExpectIntEQ(respDec.status, WC_TSP_PKISTATUS_GRANTED);
|
|
ExpectIntEQ(wc_TspResponse_Verify(&respDec, tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, &tstDec), 0);
|
|
ExpectBufEQ(tstDec.imprint.hash, tsHashedMsg, (int)sizeof(tsHashedMsg));
|
|
ExpectIntEQ(tstDec.nonceSz, (word32)sizeof(tsNonce));
|
|
ExpectBufEQ(tstDec.nonce, tsNonce, (int)sizeof(tsNonce));
|
|
ExpectIntEQ(tstDec.serialSz, (word32)sizeof(tsSerial));
|
|
ExpectBufEQ(tstDec.serial, tsSerial, (int)sizeof(tsSerial));
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* Create a time-stamp token like CMS SignedData with the given signed
|
|
* attributes - no SigningCertificateV2 added. */
|
|
static int test_tsp_token_with_attribs(WC_RNG* rng, PKCS7Attrib* attribs,
|
|
word32 attribsSz, byte* out, word32* outSz)
|
|
{
|
|
EXPECT_DECLS;
|
|
/* id-ct-TSTInfo: 1.2.840.113549.1.9.16.1.4. */
|
|
static const byte tstInfoOid[] = {
|
|
0x06, 0x0b,
|
|
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04
|
|
};
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
TspTstInfo tst;
|
|
byte tstDer[256];
|
|
word32 tstDerSz = (word32)sizeof(tstDer);
|
|
int sz = 0;
|
|
|
|
test_tsp_set_tstinfo(&tst);
|
|
ExpectIntEQ(wc_TspTstInfo_Encode(&tst, tstDer, &tstDerSz), 0);
|
|
|
|
ExpectIntEQ(test_tsp_new_tsa_signer(&pkcs7, rng), TEST_SUCCESS);
|
|
ExpectIntEQ(wc_PKCS7_SetContentType(pkcs7, (byte*)tstInfoOid,
|
|
(word32)sizeof(tstInfoOid)), 0);
|
|
if (EXPECT_SUCCESS()) {
|
|
pkcs7->content = tstDer;
|
|
pkcs7->contentSz = tstDerSz;
|
|
pkcs7->signedAttribs = attribs;
|
|
pkcs7->signedAttribsSz = attribsSz;
|
|
}
|
|
ExpectIntGT(sz = wc_PKCS7_EncodeSignedData(pkcs7, out, *outSz), 0);
|
|
if (EXPECT_SUCCESS()) {
|
|
*outSz = (word32)sz;
|
|
}
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
return EXPECT_RESULT();
|
|
}
|
|
#endif
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_ess_no_attrib(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
byte token[3072];
|
|
word32 tokenSz;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* Signing certificate attribute must be present. */
|
|
tokenSz = (word32)sizeof(token);
|
|
ExpectIntEQ(test_tsp_token_with_attribs(&rng, NULL, 0, token, &tokenSz),
|
|
TEST_SUCCESS);
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, NULL),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_ess_bad_hash(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* id-aa-signingCertificateV2: 1.2.840.113549.1.9.16.2.47. */
|
|
static const byte signCertV2Oid[] = {
|
|
0x06, 0x0b,
|
|
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x2f
|
|
};
|
|
/* SigningCertificateV2 with a certHash that matches no certificate. */
|
|
static const byte badSignCertV2[] = {
|
|
0x30, 0x26, 0x30, 0x24, 0x30, 0x22, 0x04, 0x20,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
PKCS7Attrib attrib;
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
byte token[3072];
|
|
word32 tokenSz;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* Signing certificate attribute must match the signer's certificate. */
|
|
XMEMSET(&attrib, 0, sizeof(attrib));
|
|
attrib.oid = signCertV2Oid;
|
|
attrib.oidSz = (word32)sizeof(signCertV2Oid);
|
|
attrib.value = badSignCertV2;
|
|
attrib.valueSz = (word32)sizeof(badSignCertV2);
|
|
tokenSz = (word32)sizeof(token);
|
|
ExpectIntEQ(test_tsp_token_with_attribs(&rng, &attrib, 1, token, &tokenSz),
|
|
TEST_SUCCESS);
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, NULL),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_ess_bad_alg(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* id-aa-signingCertificateV2: 1.2.840.113549.1.9.16.2.47. */
|
|
static const byte signCertV2Oid[] = {
|
|
0x06, 0x0b,
|
|
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x2f
|
|
};
|
|
/* SigningCertificateV2 with a hash algorithm - 1.2.3.4 - that is not a
|
|
* hash. */
|
|
static const byte badAlgSignCertV2[] = {
|
|
0x30, 0x0e, 0x30, 0x0c, 0x30, 0x0a,
|
|
0x30, 0x05, 0x06, 0x03, 0x2a, 0x03, 0x04,
|
|
0x04, 0x01, 0x00
|
|
};
|
|
PKCS7Attrib attrib;
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
byte token[3072];
|
|
word32 tokenSz;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* Signing certificate attribute's hash algorithm must be available. */
|
|
XMEMSET(&attrib, 0, sizeof(attrib));
|
|
attrib.oid = signCertV2Oid;
|
|
attrib.oidSz = (word32)sizeof(signCertV2Oid);
|
|
attrib.value = badAlgSignCertV2;
|
|
attrib.valueSz = (word32)sizeof(badAlgSignCertV2);
|
|
tokenSz = (word32)sizeof(token);
|
|
ExpectIntEQ(test_tsp_token_with_attribs(&rng, &attrib, 1, token, &tokenSz),
|
|
TEST_SUCCESS);
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, NULL),
|
|
WC_NO_ERR_TRACE(HASH_TYPE_E));
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_ess_v1(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
#ifndef NO_SHA
|
|
/* id-aa-signingCertificate: 1.2.840.113549.1.9.16.2.12. */
|
|
static const byte signCertOid[] = {
|
|
0x06, 0x0b,
|
|
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0c
|
|
};
|
|
byte signCertV1[8 + WC_SHA_DIGEST_SIZE];
|
|
PKCS7Attrib attrib;
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
byte token[3072];
|
|
word32 tokenSz;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* SigningCertificate of ESS - RFC 2634 - with SHA-1 hash accepted. */
|
|
signCertV1[0] = 0x30;
|
|
signCertV1[1] = 0x1a;
|
|
signCertV1[2] = 0x30;
|
|
signCertV1[3] = 0x18;
|
|
signCertV1[4] = 0x30;
|
|
signCertV1[5] = 0x16;
|
|
signCertV1[6] = 0x04;
|
|
signCertV1[7] = 0x14;
|
|
ExpectIntEQ(wc_ShaHash(tsa_cert_der_2048, sizeof_tsa_cert_der_2048,
|
|
signCertV1 + 8), 0);
|
|
XMEMSET(&attrib, 0, sizeof(attrib));
|
|
attrib.oid = signCertOid;
|
|
attrib.oidSz = (word32)sizeof(signCertOid);
|
|
attrib.value = signCertV1;
|
|
attrib.valueSz = (word32)sizeof(signCertV1);
|
|
tokenSz = (word32)sizeof(token);
|
|
ExpectIntEQ(test_tsp_token_with_attribs(&rng, &attrib, 1, token, &tokenSz),
|
|
TEST_SUCCESS);
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
#if WC_TSP_MIN_HASH_STRENGTH_BITS > 80
|
|
/* SHA-1 of ESS SigningCertificate is below the minimum strength. */
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, NULL),
|
|
WC_NO_ERR_TRACE(HASH_TYPE_E));
|
|
#else
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, NULL), 0);
|
|
#endif
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_ecc(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && defined(HAVE_ECC) && \
|
|
defined(USE_CERT_BUFFERS_256) && !defined(NO_SHA256) && \
|
|
!defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
WC_RNG rng;
|
|
TspTstInfo tstDec;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
|
|
/* Sign the token with the ECC TSA. */
|
|
ExpectIntEQ(test_tsp_make_token(token, &tokenSz, tsa_ecc_cert_der_256,
|
|
sizeof_tsa_ecc_cert_der_256, tsa_ecc_key_der_256,
|
|
sizeof_tsa_ecc_key_der_256, ECDSAk, &rng), TEST_SUCCESS);
|
|
|
|
/* Verify the ECDSA signed token. */
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, &tstDec), 0);
|
|
ExpectIntEQ(tstDec.version, WC_TSP_VERSION);
|
|
ExpectBufEQ(tstDec.imprint.hash, tsHashedMsg,
|
|
(int)sizeof(tsHashedMsg));
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_CheckTsaName(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* Name of TSA: dNSName GeneralName. */
|
|
static const byte tsaName[] = { 0x82, 0x03, 't', 's', 'a' };
|
|
/* A different name of the same length. */
|
|
static const byte otherName[] = { 0x82, 0x03, 't', 's', 'b' };
|
|
TspTstInfo tst;
|
|
|
|
ExpectIntEQ(wc_TspTstInfo_Init(&tst), 0);
|
|
|
|
/* Bad arguments. */
|
|
ExpectIntEQ(wc_TspTstInfo_CheckTsaName(NULL, tsaName,
|
|
(word32)sizeof(tsaName)), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_CheckTsaName(&tst, NULL, (word32)sizeof(tsaName)),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
ExpectIntEQ(wc_TspTstInfo_CheckTsaName(&tst, tsaName, 0),
|
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
|
|
|
/* TSA name must be present when expected. */
|
|
ExpectIntEQ(wc_TspTstInfo_CheckTsaName(&tst, tsaName,
|
|
(word32)sizeof(tsaName)), WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
|
|
/* TSA name is the expected name. */
|
|
tst.tsa = tsaName;
|
|
tst.tsaSz = (word32)sizeof(tsaName);
|
|
ExpectIntEQ(wc_TspTstInfo_CheckTsaName(&tst, tsaName,
|
|
(word32)sizeof(tsaName)), 0);
|
|
/* Expected name of a different length. */
|
|
ExpectIntEQ(wc_TspTstInfo_CheckTsaName(&tst, tsaName,
|
|
(word32)sizeof(tsaName) - 1), WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
/* Expected name with different data. */
|
|
ExpectIntEQ(wc_TspTstInfo_CheckTsaName(&tst, otherName,
|
|
(word32)sizeof(otherName)), WC_NO_ERR_TRACE(TSP_VERIFY_E));
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* Build a token whose TSTInfo carries the given TSA name. The signing PKCS7
|
|
* is created and freed here so the verifying caller news only its own. */
|
|
static int test_tsp_make_tsa_name_token(WC_RNG* rng, const byte* tsa,
|
|
word32 tsaSz, byte* token, word32* tokenSz)
|
|
{
|
|
EXPECT_DECLS;
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
TspTstInfo tst;
|
|
|
|
test_tsp_set_tstinfo(&tst);
|
|
tst.tsa = tsa;
|
|
tst.tsaSz = tsaSz;
|
|
|
|
ExpectIntEQ(test_tsp_new_tsa_signer(&pkcs7, rng), TEST_SUCCESS);
|
|
ExpectIntEQ(wc_TspTstInfo_SignWithPkcs7(&tst, pkcs7, token, tokenSz), 0);
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
/* Create and verify a token with a TSA name in the TSTInfo. */
|
|
static int test_tsp_tsa_name(WC_RNG* rng, const byte* tsa, word32 tsaSz,
|
|
int expRet)
|
|
{
|
|
EXPECT_DECLS;
|
|
wc_PKCS7* pkcs7 = NULL;
|
|
TspTstInfo tstDec;
|
|
byte token[3072];
|
|
word32 tokenSz = (word32)sizeof(token);
|
|
|
|
ExpectIntEQ(test_tsp_make_tsa_name_token(rng, tsa, tsaSz, token, &tokenSz),
|
|
TEST_SUCCESS);
|
|
|
|
ExpectNotNull(pkcs7 = wc_PKCS7_New(NULL, testDevId));
|
|
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, NULL, 0), 0);
|
|
ExpectIntEQ(wc_TspTstInfo_VerifyWithPKCS7(pkcs7, token, tokenSz, &tstDec),
|
|
expRet);
|
|
if (expRet == 0) {
|
|
/* TSA name decoded is the expected name. */
|
|
ExpectIntEQ(wc_TspTstInfo_CheckTsaName(&tstDec, tsa, tsaSz), 0);
|
|
}
|
|
wc_PKCS7_Free(pkcs7);
|
|
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
#if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
|
|
/* Make a directoryName GeneralName with the subject of the certificate. */
|
|
static int test_tsp_cert_dirname(const byte* certDer, word32 certDerSz,
|
|
byte* out, word32* outSz)
|
|
{
|
|
EXPECT_DECLS;
|
|
DecodedCert cert;
|
|
word32 idx = 0;
|
|
word32 nameLen = 0;
|
|
|
|
wc_InitDecodedCert(&cert, certDer, certDerSz, NULL);
|
|
ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL), 0);
|
|
if (EXPECT_SUCCESS()) {
|
|
nameLen = (word32)cert.subjectRawLen;
|
|
}
|
|
ExpectNotNull(cert.subjectRaw);
|
|
ExpectIntLE(2 + 3 + 3 + nameLen, *outSz);
|
|
if (EXPECT_SUCCESS()) {
|
|
word32 seqLen = 2 + nameLen + ((nameLen >= 128) ? 1 : 0);
|
|
|
|
/* directoryName [4] of GeneralName - explicitly tagged Name. */
|
|
out[idx++] = ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | ASN_DIR_TYPE;
|
|
if (seqLen >= 128) {
|
|
out[idx++] = 0x81;
|
|
}
|
|
out[idx++] = (byte)seqLen;
|
|
out[idx++] = ASN_SEQUENCE | ASN_CONSTRUCTED;
|
|
if (nameLen >= 128) {
|
|
out[idx++] = 0x81;
|
|
}
|
|
out[idx++] = (byte)nameLen;
|
|
XMEMCPY(out + idx, cert.subjectRaw, nameLen);
|
|
*outSz = idx + nameLen;
|
|
}
|
|
wc_FreeDecodedCert(&cert);
|
|
|
|
return EXPECT_RESULT();
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_tsa_name(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* dNSName of the TSA's certificate. */
|
|
static const byte goodDns[] = {
|
|
0x82, 0x0f,
|
|
't', 's', 'a', '.', 'w', 'o', 'l', 'f', 's', 's', 'l', '.', 'c',
|
|
'o', 'm'
|
|
};
|
|
WC_RNG rng;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
/* TSA name in subject alternative names of certificate. */
|
|
ExpectIntEQ(test_tsp_tsa_name(&rng, goodDns, (word32)sizeof(goodDns), 0),
|
|
TEST_SUCCESS);
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_tsa_name_mismatch(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* dNSName not of the TSA's certificate. */
|
|
static const byte badDns[] = {
|
|
0x82, 0x0f,
|
|
't', 's', 'b', '.', 'w', 'o', 'l', 'f', 's', 's', 'l', '.', 'c',
|
|
'o', 'm'
|
|
};
|
|
WC_RNG rng;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
/* TSA name not in subject alternative names of certificate. */
|
|
ExpectIntEQ(test_tsp_tsa_name(&rng, badDns, (word32)sizeof(badDns),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E)), TEST_SUCCESS);
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_tsa_name_unsupported(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* otherName - form of GeneralName not supported. */
|
|
static const byte otherName[] = { 0xa0, 0x02, 0x05, 0x00 };
|
|
WC_RNG rng;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
/* Form of GeneralName not supported. */
|
|
ExpectIntEQ(test_tsp_tsa_name(&rng, otherName, (word32)sizeof(otherName),
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E)), TEST_SUCCESS);
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_tsa_name_bad_enc(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER)
|
|
/* dNSName with a length longer than the data. */
|
|
static const byte badLen[] = { 0x82, 0x05, 't' };
|
|
#if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
|
|
/* directoryName that does not hold a SEQUENCE. */
|
|
static const byte badDirName[] = { 0xa4, 0x02, 0x31, 0x00 };
|
|
#endif
|
|
WC_RNG rng;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
/* Invalid GeneralName encoding. */
|
|
ExpectIntEQ(test_tsp_tsa_name(&rng, badLen, (word32)sizeof(badLen),
|
|
WC_NO_ERR_TRACE(ASN_PARSE_E)), TEST_SUCCESS);
|
|
#if !defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT)
|
|
/* directoryName must hold a Name. */
|
|
ExpectIntEQ(test_tsp_tsa_name(&rng, badDirName, (word32)sizeof(badDirName),
|
|
WC_NO_ERR_TRACE(ASN_PARSE_E)), TEST_SUCCESS);
|
|
#endif
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|
|
|
|
int test_wc_TspTstInfo_VerifyWithPKCS7_tsa_name_dirname(void)
|
|
{
|
|
EXPECT_DECLS;
|
|
#if defined(WOLFSSL_TSP) && defined(HAVE_PKCS7) && !defined(NO_RSA) && \
|
|
!defined(NO_SHA256) && !defined(WC_NO_RNG) && \
|
|
defined(WOLFSSL_TSP_REQUESTER) && defined(WOLFSSL_TSP_RESPONDER) && \
|
|
(!defined(IGNORE_NAME_CONSTRAINTS) || defined(WOLFSSL_CERT_EXT))
|
|
byte dirName[256];
|
|
word32 dirNameSz;
|
|
WC_RNG rng;
|
|
|
|
ExpectIntEQ(wc_InitRng(&rng), 0);
|
|
/* TSA name is subject name of certificate. */
|
|
dirNameSz = (word32)sizeof(dirName);
|
|
ExpectIntEQ(test_tsp_cert_dirname(tsa_cert_der_2048,
|
|
sizeof_tsa_cert_der_2048, dirName, &dirNameSz), TEST_SUCCESS);
|
|
ExpectIntEQ(test_tsp_tsa_name(&rng, dirName, dirNameSz, 0), TEST_SUCCESS);
|
|
/* TSA name is subject name of another certificate. */
|
|
dirNameSz = (word32)sizeof(dirName);
|
|
ExpectIntEQ(test_tsp_cert_dirname(client_cert_der_2048,
|
|
sizeof_client_cert_der_2048, dirName, &dirNameSz), TEST_SUCCESS);
|
|
ExpectIntEQ(test_tsp_tsa_name(&rng, dirName, dirNameSz,
|
|
WC_NO_ERR_TRACE(TSP_VERIFY_E)), TEST_SUCCESS);
|
|
wc_FreeRng(&rng);
|
|
#endif
|
|
return EXPECT_RESULT();
|
|
}
|