Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions src/x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -11711,14 +11711,33 @@ WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_sk_X509_OBJECT_deep_copy(
cert->isCA = req->isCa;
cert->basicConstSet = req->basicConstSet;
#ifdef WOLFSSL_CERT_EXT
if (req->subjKeyIdSz != 0) {
XMEMCPY(cert->skid, req->subjKeyId, req->subjKeyIdSz);
cert->skidSz = (int)req->subjKeyIdSz;
if (req->subjKeyIdSz > CTC_MAX_SKID_SIZE) {
WOLFSSL_MSG("Subject Key ID too large");
WOLFSSL_ERROR_VERBOSE(BUFFER_E);
cert->skidSz = 0;
ret = WOLFSSL_FAILURE;
}
else if (req->subjKeyIdSz > 0) {
if (req->subjKeyId == NULL) {
WOLFSSL_MSG("Subject Key ID missing");
WOLFSSL_ERROR_VERBOSE(BAD_FUNC_ARG);
cert->skidSz = 0;
ret = WOLFSSL_FAILURE;
}
else {
XMEMCPY(cert->skid, req->subjKeyId, req->subjKeyIdSz);
cert->skidSz = (int)req->subjKeyIdSz;
}
}
else {
cert->skidSz = 0;
}
if (req->keyUsageSet)
cert->keyUsage = req->keyUsage;
if (ret == WOLFSSL_SUCCESS) {
if (req->keyUsageSet)
cert->keyUsage = req->keyUsage;

cert->extKeyUsage = req->extKeyUsage;
cert->extKeyUsage = req->extKeyUsage;
}
#endif

XMEMCPY(cert->challengePw, req->challengePw, CTC_NAME_SIZE);
Expand Down
179 changes: 179 additions & 0 deletions tests/api/test_x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -875,3 +875,182 @@ int test_x509_CertFromX509_akid_overflow(void)
#endif
return EXPECT_RESULT();
}

/* Test that ReqCertFromX509 rejects an oversized SubjectKeyIdentifier
* extension when re-encoding a parsed CSR. */
int test_x509_ReqCertFromX509_skid_overflow(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) && \
defined(WOLFSSL_CERT_REQ) && !defined(NO_BIO) && \
(defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL))
#ifdef WOLFSSL_SMALL_STACK
unsigned char* buf = NULL;
#else
unsigned char buf[16384];
#endif
size_t pos = 0;
WOLFSSL_X509* req = NULL;
WOLFSSL_BIO* bio = NULL;
unsigned char* der = NULL;

#ifdef WOLFSSL_SMALL_STACK
buf = (unsigned char*)XMALLOC(16384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ExpectNotNull(buf);
if (buf == NULL)
return EXPECT_RESULT();
#endif

#define PUT1(b) do { buf[pos++] = (b); } while(0)
#define PUTN(p, n) do { XMEMCPY(buf + pos, (p), (n)); pos += (n); } while(0)

#define TLV_HDR(tag, n, out, hlen) do { \
size_t _i = 0; \
(out)[_i++] = (tag); \
if ((n) < 0x80u) { (out)[_i++] = (unsigned char)(n); } \
else if ((n) < 0x100u) { (out)[_i++] = 0x81; \
(out)[_i++] = (unsigned char)(n); } \
else if ((n) < 0x10000u) { (out)[_i++] = 0x82; \
(out)[_i++] = (unsigned char)((n)>>8); \
(out)[_i++] = (unsigned char)(n); } \
(hlen) = _i; \
} while(0)

#define WRAP(start, tag) do { \
size_t _len = pos - (start); \
unsigned char _hdr[6]; size_t _hlen; \
TLV_HDR((tag), _len, _hdr, _hlen); \
XMEMMOVE(buf + (start) + _hlen, buf + (start), _len); \
XMEMCPY(buf + (start), _hdr, _hlen); \
pos += _hlen; \
} while(0)

{
size_t req_start = pos;
size_t s;
int i;

/* CertificationRequestInfo */
s = pos;
/* version = v1 */
PUT1(0x02); PUT1(0x01); PUT1(0x00);

/* subject: CN=A */
{
size_t name = pos, rdn = pos, atv = pos;
unsigned char cn[] = {0x06,0x03,0x55,0x04,0x03};
PUTN(cn, sizeof(cn));
PUT1(0x0C); PUT1(0x01); PUT1('A');
WRAP(atv, 0x30);
WRAP(rdn, 0x31);
WRAP(name, 0x30);
}

/* subjectPublicKeyInfo: EC P-256 with generator point */
{
size_t spki = pos, alg = pos, bs;
unsigned char ecpk[] = {0x06,0x07,0x2A,0x86,0x48,0xCE,
0x3D,0x02,0x01};
unsigned char p256[] = {0x06,0x08,0x2A,0x86,0x48,0xCE,
0x3D,0x03,0x01,0x07};
static const unsigned char p256G[64] = {
0x6B,0x17,0xD1,0xF2,0xE1,0x2C,0x42,0x47,
0xF8,0xBC,0xE6,0xE5,0x63,0xA4,0x40,0xF2,
0x77,0x03,0x7D,0x81,0x2D,0xEB,0x33,0xA0,
0xF4,0xA1,0x39,0x45,0xD8,0x98,0xC2,0x96,
0x4F,0xE3,0x42,0xE2,0xFE,0x1A,0x7F,0x9B,
0x8E,0xE7,0xEB,0x4A,0x7C,0x0F,0x9E,0x16,
0x2B,0xCE,0x33,0x57,0x6B,0x31,0x5E,0xCE,
0xCB,0xB6,0x40,0x68,0x37,0xBF,0x51,0xF5
};
PUTN(ecpk, sizeof(ecpk));
PUTN(p256, sizeof(p256));
WRAP(alg, 0x30);
bs = pos;
PUT1(0x00);
PUT1(0x04);
PUTN(p256G, sizeof(p256G));
WRAP(bs, 0x03);
WRAP(spki, 0x30);
}

/* attributes [0]: extensionRequest(subjectKeyIdentifier) */
{
size_t attrs = pos, attr = pos, values, exts;
size_t ext, extVal, skid;
unsigned char extReqOid[] = {0x06,0x09,0x2A,0x86,0x48,0x86,
0xF7,0x0D,0x01,0x09,0x0E};
unsigned char skidOid[] = {0x06,0x03,0x55,0x1D,0x0E};

PUTN(extReqOid, sizeof(extReqOid));
values = pos;
exts = pos;
ext = pos;
PUTN(skidOid, sizeof(skidOid));
extVal = pos;
skid = pos;
for (i = 0; i < CTC_MAX_SKID_SIZE + 1; i++) {
PUT1((unsigned char)(0x41 + (i % 16)));
}
WRAP(skid, 0x04);
WRAP(extVal, 0x04);
WRAP(ext, 0x30);
WRAP(exts, 0x30);
WRAP(values, 0x31);
WRAP(attr, 0x30);
WRAP(attrs, 0xA0);
}
WRAP(s, 0x30);

/* signatureAlgorithm: ecdsa-with-SHA256 */
s = pos;
{
unsigned char oid[] = {0x06,0x08,0x2A,0x86,0x48,0xCE,
0x3D,0x04,0x03,0x02};
PUTN(oid, sizeof(oid));
}
WRAP(s, 0x30);

/* signatureValue: parser does not verify this for the regression */
s = pos;
{
size_t sig;

PUT1(0x00);
sig = pos;
PUT1(0x02); PUT1(0x01); PUT1(0x01);
PUT1(0x02); PUT1(0x01); PUT1(0x01);
WRAP(sig, 0x30);
}
WRAP(s, 0x03);
WRAP(req_start, 0x30);
}

req = wolfSSL_X509_REQ_d2i(NULL, buf, (int)pos);
ExpectNotNull(req);
if (req != NULL) {
ExpectIntEQ((int)req->subjKeyIdSz, CTC_MAX_SKID_SIZE + 1);
}

bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
ExpectNotNull(bio);
if ((req != NULL) && (bio != NULL)) {
ExpectIntEQ(wolfSSL_i2d_X509_REQ_bio(bio, req), WOLFSSL_FAILURE);
ExpectIntEQ(wolfSSL_i2d_X509_REQ(req, &der),
WC_NO_ERR_TRACE(WOLFSSL_FAILURE));
ExpectNull(der);
}

wolfSSL_BIO_free(bio);
wolfSSL_X509_free(req);
#ifdef WOLFSSL_SMALL_STACK
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif

#undef PUT1
#undef PUTN
#undef TLV_HDR
#undef WRAP
#endif
return EXPECT_RESULT();
}
4 changes: 3 additions & 1 deletion tests/api/test_x509.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ int test_x509_set_serialNumber(void);
int test_x509_verify_cert_hostname_check(void);
int test_x509_time_field_overread_via_tls(void);
int test_x509_CertFromX509_akid_overflow(void);
int test_x509_ReqCertFromX509_skid_overflow(void);

#define TEST_X509_DECLS \
TEST_DECL_GROUP("x509", test_x509_rfc2818_verification_callback), \
TEST_DECL_GROUP("x509", test_x509_GetCAByAKID), \
TEST_DECL_GROUP("x509", test_x509_set_serialNumber), \
TEST_DECL_GROUP("x509", test_x509_verify_cert_hostname_check), \
TEST_DECL_GROUP("x509", test_x509_time_field_overread_via_tls), \
TEST_DECL_GROUP("x509", test_x509_CertFromX509_akid_overflow)
TEST_DECL_GROUP("x509", test_x509_CertFromX509_akid_overflow), \
TEST_DECL_GROUP("x509", test_x509_ReqCertFromX509_skid_overflow)

#endif /* WOLFCRYPT_TEST_X509_H */
Loading