X509 attribute cert (acert) support.

pull/7926/head
jordan 2024-09-13 08:03:55 -05:00
parent 4fa20cb770
commit 7faed6cded
22 changed files with 2600 additions and 94 deletions

View File

@ -0,0 +1,23 @@
-----BEGIN ATTRIBUTE CERTIFICATE-----
MIID4zCCAssCAQEwOaA3MB+kHTAbMRkwFwYDVQQDDBBUUE0gTWFudWZhY3R1cmVy
AhRADHoGLYO7i9GfV2Yz2rrlRFDPSqA6MDikNjA0MQswCQYDVQQGEwJVUzEUMBIG
A1UECgwLZXhhbXBsZS5jb20xDzANBgNVBAsMBlBDVGVzdDANBgkqhkiG9w0BAQsF
AAIBATAiGA8yMDE4MDEwMTA1MDAwMFoYDzIwMjgwMTAxMDUwMDAwWjCB7TALBgVn
gQUCEzECMAAwHAYFZ4EFAhExEzARMAkCAQECAQMCARYEBAAAAAEwEgYFZ4EFAhkx
CTAHBgVngQUIAjCBlQYHZ4EFBQEHAjGBiTCBhqBkMC8wDgYGZ4EFEgMBBAQAAgAB
DBJYWVogQ29tcHV0aW5nIEluYy4MATGABkFCQzEyMzAxMA4GBmeBBRIDAQQEAAcA
AgwNTm90IFNwZWNpZmllZAwDSEQxgAgxMjM0QUJDRIMB/6IeMBwMCHVuYW1lIC1y
DBA2LjUuMC0xNS1nZW5lcmljMBQGBWeBBQIXMQswCQIBAQIBAQIBETCCAScwbwYD
VR0jBGgwZoAUl46DRCrPD3GZndkBbbNDngf6ZHChOKQ2MDQxCzAJBgNVBAYTAlVT
MRQwEgYDVQQKDAtleGFtcGxlLmNvbTEPMA0GA1UECwwGUENUZXN0ghRmuv6Ey2Ja
dCAOFysMNOn9CiH45zBBBgNVHSAEOjA4MDYGAioDMDAwLgYIKwYBBQUHAgIwIgwg
VENHIFRydXN0ZWQgUGxhdGZvcm0gRW5kb3JzZW1lbnQwcQYDVR0RBGowaKRmMGQx
EzARBgZngQUFAQQMB01vZGVsIEExHjAcBgZngQUFAQEMElhZWiBDb21wdXRpbmcg
SW5jLjEZMBcGBmeBBQUBBQwNTm90IFNwZWNpZmllZDESMBAGBmeBBQUBBgwGQUJD
MTIzMA0GCSqGSIb3DQEBCwUAA4IBAQB2SdELM7Dqaq2mvT+IV3pCBN7qPzRL+sO4
MZG6jpTbbblr124KM84g936zLVZxOJeAa+Ie7r0ET7GYI+zKtpLmIZrlqhZl4YkP
3g65JsIVc5PvOogxv67IxVigHu/NFKHIbFPz85drTatEVCfA8ac8BwJXXwuESLNr
cH+K/vdLWDgMhsijhco82RI8x11wBvzMXLPnM5OnkiG/0zaEW7mk1gH2tBS6oCc+
0v8y9jQ5NqyPo0mNhLJhUMonmvaGdZ3iDEFyF+iNuDc3pP5PA1YDKk/BYGXt1NUE
89mkuGoF8bwkU9uqLKQ3jpCKx/SZZ08IK5MPQyzsnwjyhrsrP3Qm
-----END ATTRIBUTE CERTIFICATE-----

View File

@ -0,0 +1,15 @@
-----BEGIN ATTRIBUTE CERTIFICATE-----
MIICPTCCASUCAQEwN6AWMBGkDzANMQswCQYDVQQDDAJDQQIBAqEdpBswGTEXMBUG
A1UEAwwOc2VydmVyLmV4YW1wbGWgLTArpCkwJzElMCMGA1UEAwwcQXR0cmlidXRl
IENlcnRpZmljYXRlIElzc3VlcjANBgkqhkiG9w0BAQsFAAIUA7WQWQKiqrVAIUS4
LE/ZgBtfV8IwIhgPMjAyMTA2MTUxMjM1MDBaGA8yMDMxMDYxMzEyMzUwMFowQTAj
BggrBgEFBQcKBDEXMBWgCYYHVGVzdHZhbDAIDAZncm91cDEwGgYDVQRIMRMwEaEP
gw1hZG1pbmlzdHJhdG9yMCwwHwYDVR0jBBgwFoAUYm7JaGdsZLtTgt0tqoCK2MrI
i10wCQYDVR04BAIFADANBgkqhkiG9w0BAQsFAAOCAQEAlIOJ2Dj3TEUj6BIv6vUs
GqFWms05i+d10XSzWrunlUTQPoJcUjYkifOWp/7RpZ2XnRl+6hH+nIbmwSmXWwBn
ERw2bQMmw//nWuN4Qv9t7ltuovWC0pJX6VMT1IRTuTV4SxuZpFL37vkmnFlPBlb+
mn3ESSxLTjThWFIq1tip4IaxE/i5Uh32GlJglatFHM1PCGoJtyLtYb6KHDlvknw6
coDyjIcj0FZwtQw41jLwxI8jWNmrpt978wdpprB/URrRs+m02HmeQoiHFi/qvdv8
d+5vHf3Pi/ulhz/+dvr0p1vEQSoFnYxLXuty2p5m3PJPZCFmT3gURgmgR3BN9d7A
Bw==
-----END ATTRIBUTE CERTIFICATE-----

View File

@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqvpigJZE2asRTFe63b3f
xvh0swQuX+L4hW08E7mlm0NSQvBVs8yebELNnZLL738fvocvQMwAjf+8+Lyjb1fr
FYMYvJpb6LmGA2Ysyt6Ny700dpiUValtd4mwtjSCH0/k4rCiaiCYWaN79Le9ZGwD
pZ341kVX74JkNdaXs1EJ1tkUUoq6aIu5CWYncxjA4IufduHV1Eh/dpNq1tuLHjgY
Y3NwYDJcotmN9mmIO+MAuZ1TzifhIy14tNGIspYpSZbn8j2RQpQOclhMVWeM5t0i
TWgOO+jhJngptIJMXEaQQzKPiazv6pBhk8oamAZ0Nipr+DI8iDxvzHtyFDRVToOg
1QIDAQAB
-----END PUBLIC KEY-----

View File

@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArjl1VnpENuEfQCVm2E4q
h28D62c0pX5IgN5F2RoS7siU2Oc9hsSz6Hj+9o0SRhUTEAxxrML2d7TM2SVoIJ/x
CFrchA1fIZQm7FWJa7MDFpxkRc7cNUGrZ5oyVCHtK6IbKiU4y8B/vova6+dyy6bi
j97ea0UDL8ztKNyDUH9ZntyFrHTltA/ZlEjmxGHQJQd4RBO6RdfM70R7l+YTGa2N
PflyiRY2SKNXXx8cVUURJvkOXVfLCuRUzG+NnSS62WRuWOOD0ZjiJCnwkTJZQNw0
qI+hLhWN+//05JeKOw6rNVVUHR/R0GgjPL6FIQ/+yF2Z8nCd8lVIIY+hQsM/1l/h
2QIDAQAB
-----END PUBLIC KEY-----

View File

@ -0,0 +1,13 @@
# vim:ft=automake
# All paths should be given relative to the root
#
EXTRA_DIST += \
certs/acert/acert.pem \
certs/acert/acert_ietf.pem \
certs/acert/acert_pubkey.pem \
certs/acert/acert_ietf_pubkey.pem \
certs/acert/rsa_pss/acert.pem \
certs/acert/rsa_pss/acert_ietf.pem \
certs/acert/rsa_pss/acert_pubkey.pem \
certs/acert/rsa_pss/acert_ietf_pubkey.pem

View File

@ -0,0 +1,25 @@
-----BEGIN ATTRIBUTE CERTIFICATE-----
MIIESzCCAv8CAQEwOaA3MB+kHTAbMRkwFwYDVQQDDBBUUE0gTWFudWZhY3R1cmVy
AhRADHoGLYO7i9GfV2Yz2rrlRFDPSqA6MDikNjA0MQswCQYDVQQGEwJVUzEUMBIG
A1UECgwLZXhhbXBsZS5jb20xDzANBgNVBAsMBlBDVGVzdDBBBgkqhkiG9w0BAQow
NKAPMA0GCWCGSAFlAwQCAQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUA
ogMCASACAQEwIhgPMjAxODAxMDEwNTAwMDBaGA8yMDI4MDEwMTA1MDAwMFowge0w
CwYFZ4EFAhMxAjAAMBwGBWeBBQIRMRMwETAJAgEBAgEDAgEWBAQAAAABMBIGBWeB
BQIZMQkwBwYFZ4EFCAIwgZUGB2eBBQUBBwIxgYkwgYagZDAvMA4GBmeBBRIDAQQE
AAIAAQwSWFlaIENvbXB1dGluZyBJbmMuDAExgAZBQkMxMjMwMTAOBgZngQUSAwEE
BAAHAAIMDU5vdCBTcGVjaWZpZWQMA0hEMYAIMTIzNEFCQ0SDAf+iHjAcDAh1bmFt
ZSAtcgwQNi41LjAtMTUtZ2VuZXJpYzAUBgVngQUCFzELMAkCAQECAQECAREwggEn
MG8GA1UdIwRoMGaAFJeOg0Qqzw9xmZ3ZAW2zQ54H+mRwoTikNjA0MQswCQYDVQQG
EwJVUzEUMBIGA1UECgwLZXhhbXBsZS5jb20xDzANBgNVBAsMBlBDVGVzdIIUZrr+
hMtiWnQgDhcrDDTp/Qoh+OcwQQYDVR0gBDowODA2BgIqAzAwMC4GCCsGAQUFBwIC
MCIMIFRDRyBUcnVzdGVkIFBsYXRmb3JtIEVuZG9yc2VtZW50MHEGA1UdEQRqMGik
ZjBkMRMwEQYGZ4EFBQEEDAdNb2RlbCBBMR4wHAYGZ4EFBQEBDBJYWVogQ29tcHV0
aW5nIEluYy4xGTAXBgZngQUFAQUMDU5vdCBTcGVjaWZpZWQxEjAQBgZngQUFAQYM
BkFCQzEyMzBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQCAQUAoRwwGgYJKoZI
hvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASADggEBAH4FGu9CJJ/NraWxXoB+EuHu
Ec95MPJDHnsDLea45z5TXkdxCd8Tb5EBuWYFCI6nkpWtkiF5UaLncQD/1ag0ECjZ
duhmoaM01t8TERP1x2xOotpiS0nDGiAqn3twBS3NZlxgEDRMvW92tM49Vvlk7JwD
Kxv9+qXidCXt62dcDNJoe1Uj9HXxuOO2NaO9OQHlPkY5GctKbcDBwaDUlEz40J9k
PoXDNurLmI/nNgMDgicKdzdmhMT/BSXSt7Z228p7QcgROgJ5xTEVIMm+lGcBg1Sc
RnWTVNjrIG+/nzYZENr+F40nrIKbkIIZTLCqwAN6fFFt/jNc44SdoJMNsKe1bTM=
-----END ATTRIBUTE CERTIFICATE-----

View File

@ -0,0 +1,17 @@
-----BEGIN ATTRIBUTE CERTIFICATE-----
MIICpTCCAVkCAQEwN6AWMBGkDzANMQswCQYDVQQDDAJDQQIBAqEdpBswGTEXMBUG
A1UEAwwOc2VydmVyLmV4YW1wbGWgLTArpCkwJzElMCMGA1UEAwwcQXR0cmlidXRl
IENlcnRpZmljYXRlIElzc3VlcjBBBgkqhkiG9w0BAQowNKAPMA0GCWCGSAFlAwQC
AQUAoRwwGgYJKoZIhvcNAQEIMA0GCWCGSAFlAwQCAQUAogMCASACFAO1kFkCoqq1
QCFEuCxP2YAbX1fCMCIYDzIwMjEwNjE1MTIzNTAwWhgPMjAzMTA2MTMxMjM1MDBa
MEEwIwYIKwYBBQUHCgQxFzAVoAmGB1Rlc3R2YWwwCAwGZ3JvdXAxMBoGA1UESDET
MBGhD4MNYWRtaW5pc3RyYXRvcjAsMB8GA1UdIwQYMBaAFGJuyWhnbGS7U4LdLaqA
itjKyItdMAkGA1UdOAQCBQAwQQYJKoZIhvcNAQEKMDSgDzANBglghkgBZQMEAgEF
AKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEFAKIDAgEgA4IBAQCX18Lyj2CR
AJL9JAwxYgWbk7fWif2mG5IiQ264Rd0W6ugqw1hYseKHnRI5LpxsRVF5kEaFs2ta
FhwxxOtAo8YvbxMC4emuatbqwOlWQYwk9wPLbZb1nd1FItPtO98FK7/vF0263eJu
A+UFxmDvLlao3SzP19mtCOcUjGsVxcJ2PN05wDUzITu2vGXuJAdjHcYX+s1UMLwk
WMwHsz7EK2Al/FavI1MfZp0lVFi++CMOAdLIRbTjlACATDq6Q6kPc+bTqvMYoca2
bGLw1jSig6T3DvGa3O/BwRMOhyqCtJNQYY7MYxcZhPR4Y0RLmyFnFiSzwypL6oMk
QMaW0z/K5YO2
-----END ATTRIBUTE CERTIFICATE-----

View File

@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIDALBgkqhkiG9w0BAQoDggEPADCCAQoCggEBALg9nrRhxCl5zxFdE7Le9GXL
9M8Rzx5xU3meu6yp9lFIc3+FxNoc5E8nk7HXUK82iuEChcSlqt0j0/y03YqM+O45
N6A9OkEkjdyL8BaeQEgNxZY16/nvhhnH0Bzg4n7DMvy3sUPQvsAu9tpbfSd+WNDT
vtO9Fe84HIBkYhRuaIv7ca1UYn7R2VQk1RXK0lfY4orCOrexmlfPciJaTJcR5Lyi
pjUj7X5lruRHVibrMY+Z+8DtvPaDZ7HFiuXzpGPQ0W907Wt7zEJfmTMUyQoOMDMM
4iSlq0ib3rdZt9y2obCggRTFAtMAFIJ29FOT9FYDagMYFSqhnrR3ohiTNzfpYNMC
AwEAAQ==
-----END PUBLIC KEY-----

View File

@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIDALBgkqhkiG9w0BAQoDggEPADCCAQoCggEBAL0P9mcosJbMQavKMo6FvjK/
vC5PZAFYxsbQnDiG3kb3gCsshI8HQzHNIuw4wN3waJrqnFmsmsUqMENtsC0J2Fty
DOI5791Ma7JUKT31RW6f5eU2Gjx1+evNWtWs2WzupsZdPS3DlgEQJsTSw3Fs1q5w
JVLVHhtOjCwdj2QO9Xr17Nt0ZOfKoJdqth3LAVujMnOw9gbyTbCrCB+z1Mkq+dK4
K0v6IPZqY76LVhR42y/lyG+MZ8jswg4I4qAE+iIwPi/9Tz9UdNwMfSr3gdD13pa3
VqnGZG83prqPLEHwsSNpWGdDx7pQxgBkAPztO+7LPrMd1ck8Uugsq36pusLjdQ0C
AwEAAQ==
-----END PUBLIC KEY-----

View File

@ -148,4 +148,5 @@ include certs/rsapss/include.am
include certs/dilithium/include.am
include certs/sphincs/include.am
include certs/rpk/include.am
include certs/acert/include.am

View File

@ -3840,6 +3840,12 @@ then
ENABLED_KEYGEN=yes
fi
# ATTRIBUTE CERTIFICATES
AC_ARG_ENABLE([acert],
[AS_HELP_STRING([--enable-acert],[Enable attribute certificate support (default: disabled)])],
[ ENABLED_ACERT=$enableval ],
[ ENABLED_ACERT=no ]
)
# CERT GENERATION
AC_ARG_ENABLE([certgen],
@ -9237,6 +9243,9 @@ AS_IF([test "x$ENABLED_ALTNAMES" = "xyes"],
AS_IF([test "x$ENABLED_KEYGEN" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_KEY_GEN"])
AS_IF([test "x$ENABLED_ACERT" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ACERT"])
AS_IF([test "x$ENABLED_CERTREQ" = "xyes"],
[AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_CERT_REQ"])
@ -10227,6 +10236,7 @@ echo " * BLAKE2S: $ENABLED_BLAKE2S"
echo " * SipHash: $ENABLED_SIPHASH"
echo " * CMAC: $ENABLED_CMAC"
echo " * keygen: $ENABLED_KEYGEN"
echo " * acert: $ENABLED_ACERT"
echo " * certgen: $ENABLED_CERTGEN"
echo " * certreq: $ENABLED_CERTREQ"
echo " * certext: $ENABLED_CERTEXT"

View File

@ -12640,6 +12640,45 @@ static void AddSessionCertToChain(WOLFSSL_X509_CHAIN* chain,
}
#endif
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
defined(WOLFSSL_ACERT)
static int CopyAltNames(DNS_entry** to, DNS_entry* from, int type, void* heap)
{
/* Copy from to the beginning of to */
DNS_entry** prev_next = to;
DNS_entry* next;
if (to == NULL) {
return BAD_FUNC_ARG;
}
next = *to;
for (; from != NULL; from = from->next) {
DNS_entry* dnsEntry;
if (type != -1 && from->type != type)
continue;
dnsEntry = AltNameDup(from, heap);
if (dnsEntry == NULL) {
WOLFSSL_MSG("\tOut of Memory");
return MEMORY_E;
}
dnsEntry->next = next;
*prev_next = dnsEntry;
prev_next = &dnsEntry->next;
}
return 0;
}
#endif /* KEEP_PEER_CERT || SESSION_CERTS ||
* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL ||
* WOLFSSL_ACERT */
#if defined(KEEP_PEER_CERT) || defined(SESSION_CERTS) || \
defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
void CopyDecodedName(WOLFSSL_X509_NAME* name, DecodedCert* dCert, int nameType)
@ -12674,38 +12713,6 @@ void CopyDecodedName(WOLFSSL_X509_NAME* name, DecodedCert* dCert, int nameType)
}
}
static int CopyAltNames(DNS_entry** to, DNS_entry* from, int type, void* heap)
{
/* Copy from to the beginning of to */
DNS_entry** prev_next = to;
DNS_entry* next;
if (to == NULL) {
return BAD_FUNC_ARG;
}
next = *to;
for (; from != NULL; from = from->next) {
DNS_entry* dnsEntry;
if (type != -1 && from->type != type)
continue;
dnsEntry = AltNameDup(from, heap);
if (dnsEntry == NULL) {
WOLFSSL_MSG("\tOut of Memory");
return MEMORY_E;
}
dnsEntry->next = next;
*prev_next = dnsEntry;
prev_next = &dnsEntry->next;
}
return 0;
}
#ifdef WOLFSSL_CERT_REQ
static int CopyREQAttributes(WOLFSSL_X509* x509, DecodedCert* dCert)
{
@ -13212,6 +13219,122 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert)
#endif /* KEEP_PEER_CERT || SESSION_CERTS */
#if defined(WOLFSSL_ACERT)
/* Copy a DecodedAcert structure to an X509_ACERT.
*
* @param [out] x509 the dst X509 acert structure
* @param [in] dAcert the src decoded acert structure
*
* @return 0 on success
* @return < 0 on error
* */
int CopyDecodedAcertToX509(WOLFSSL_X509_ACERT* x509, DecodedAcert* dAcert)
{
int ret = 0;
if (x509 == NULL || dAcert == NULL) {
return BAD_FUNC_ARG;
}
/* Copy version and serial number. */
x509->version = dAcert->version + 1;
XMEMCPY(x509->serial, dAcert->serial, EXTERNAL_SERIAL_SIZE);
x509->serialSz = dAcert->serialSz;
if (dAcert->holderSerialSz > 0) {
/* This ACERT Holder field had a serial number. Copy it. */
XMEMCPY(x509->holderSerial, dAcert->holderSerial,
dAcert->holderSerialSz);
x509->holderSerialSz = dAcert->holderSerialSz;
}
/* Copy before and after dates. */
{
int minSz = 0;
if (dAcert->beforeDateLen > 0) {
minSz = (int)min(dAcert->beforeDate[1], MAX_DATE_SZ);
x509->notBefore.type = dAcert->beforeDate[0];
x509->notBefore.length = minSz;
XMEMCPY(x509->notBefore.data, &dAcert->beforeDate[2], minSz);
}
else {
x509->notBefore.length = 0;
}
if (dAcert->afterDateLen > 0) {
minSz = (int)min(dAcert->afterDate[1], MAX_DATE_SZ);
x509->notAfter.type = dAcert->afterDate[0];
x509->notAfter.length = minSz;
XMEMCPY(x509->notAfter.data, &dAcert->afterDate[2], minSz);
}
else {
x509->notAfter.length = 0;
}
}
/* Copy the signature. */
if (dAcert->signature != NULL && dAcert->sigLength != 0 &&
dAcert->sigLength <= MAX_ENCODED_SIG_SZ) {
x509->sig.buffer = (byte*)XMALLOC(
dAcert->sigLength, x509->heap, DYNAMIC_TYPE_SIGNATURE);
if (x509->sig.buffer == NULL) {
ret = MEMORY_E;
}
else {
XMEMCPY(x509->sig.buffer, dAcert->signature, dAcert->sigLength);
x509->sig.length = dAcert->sigLength;
x509->sigOID = (int)dAcert->signatureOID;
}
}
/* if der contains original source buffer then store for potential
* retrieval */
if (dAcert->source != NULL && dAcert->maxIdx > 0) {
if (AllocDer(&x509->derCert, dAcert->maxIdx, CERT_TYPE, x509->heap)
== 0) {
XMEMCPY(x509->derCert->buffer, dAcert->source, dAcert->maxIdx);
}
else {
ret = MEMORY_E;
}
}
/* Copy holder and att cert issuer names if present. */
if (CopyAltNames(&x509->holderIssuerName, dAcert->holderIssuerName,
ASN_DIR_TYPE, x509->heap) != 0) {
return MEMORY_E;
}
if (CopyAltNames(&x509->holderEntityName, dAcert->holderEntityName,
ASN_DIR_TYPE, x509->heap) != 0) {
return MEMORY_E;
}
if (CopyAltNames(&x509->AttCertIssuerName, dAcert->AttCertIssuerName,
ASN_DIR_TYPE, x509->heap) != 0) {
return MEMORY_E;
}
if (dAcert->rawAttr && dAcert->rawAttrLen > 0) {
/* Allocate space for the raw Attributes field, then copy it in. */
x509->rawAttr = (byte*)XMALLOC(dAcert->rawAttrLen, x509->heap,
DYNAMIC_TYPE_X509_EXT);
if (x509->rawAttr != NULL) {
XMEMCPY(x509->rawAttr, dAcert->rawAttr, dAcert->rawAttrLen);
x509->rawAttrLen = dAcert->rawAttrLen;
}
else {
ret = MEMORY_E;
}
}
return ret;
}
#endif /* WOLFSSL_ACERT */
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) || \
(defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && !defined(WOLFSSL_NO_TLS12))
static int ProcessCSR(WOLFSSL* ssl, byte* input, word32* inOutIdx,

View File

@ -5828,6 +5828,248 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b)
#define MAX_WIDTH 80
#endif
#if defined(WOLFSSL_ACERT)
#define ACERT_NUM_DIR_TAGS 4
/* Convenience struct and function for printing the Holder sub fields
* of an X509 Attribute struct. */
struct acert_dir_print_t {
const char * pfx;
const byte tag[3];
};
static struct acert_dir_print_t acert_dir_print[ACERT_NUM_DIR_TAGS] =
{
{ "C=", {0x55, 0x04, ASN_COUNTRY_NAME} },
{ "O=", {0x55, 0x04, ASN_ORG_NAME} },
{ "OU=", {0x55, 0x04, ASN_ORGUNIT_NAME} },
{ "CN=", {0x55, 0x04, ASN_COMMON_NAME} },
};
/* Print an entry of ASN_DIR_TYPE into dst of length max_len.
*
* Returns total_len of str on success.
* Returns < 0 on failure.
* */
static int X509PrintDirType(char * dst, int max_len, const DNS_entry * entry)
{
word32 k = 0;
word32 i = 0;
const char * src = entry->name;
word32 src_len = (word32)XSTRLEN(src);
int total_len = 0;
int bytes_left = max_len;
int fld_len = 0;
int match_found = 0;
XMEMSET(dst, 0, max_len);
/* loop over printable DIR tags. */
for (k = 0; k < ACERT_NUM_DIR_TAGS; ++k) {
const char * pfx = acert_dir_print[k].pfx;
const byte * tag = acert_dir_print[k].tag;
byte asn_tag;
/* walk through entry looking for matches. */
for (i = 0; i < src_len - 5; ++i) {
if (XMEMCMP(tag, &src[i], 3) == 0) {
if (bytes_left < 5) {
/* Not enough space left for name oid + tag + len. */
break;
}
if (match_found) {
/* append a {',', ' '} before doing anything else. */
*dst++ = ',';
*dst++ = ' ';
total_len += 2;
bytes_left -= 2;
}
i += 3;
/* Get the ASN Tag. */
if (GetASNTag((const byte *)src, &i, &asn_tag, src_len) < 0) {
WOLFSSL_MSG("error: GetASNTag failed");
break;
}
/* Check it is printable. */
if ((asn_tag != ASN_PRINTABLE_STRING) &&
(asn_tag != ASN_IA5_STRING) &&
(asn_tag != ASN_UTF8STRING)) {
/* Don't know what this is but we can't print it. */
WOLFSSL_MSG("error: asn tag not printable string");
break;
}
/* Now get the length of the printable string. */
if (GetLength((const byte *)src, &i, &fld_len, src_len) < 0) {
break;
}
/* Make sure we have space to fit it. */
if ((int) XSTRLEN(pfx) > bytes_left) {
/* Not enough space left. */
break;
}
/* Copy it in, decrement available space. */
XSTRNCPY(dst, pfx, bytes_left);
dst += XSTRLEN(pfx);
total_len += XSTRLEN(pfx);
bytes_left -= XSTRLEN(pfx);
if (fld_len > bytes_left) {
/* Not enough space left. */
break;
}
XMEMCPY(dst, &src[i], fld_len);
i += fld_len;
dst += fld_len;
total_len += fld_len;
bytes_left -= fld_len;
match_found = 1;
}
}
}
return total_len;
}
static int X509_ACERT_print_name_entry(WOLFSSL_BIO* bio,
const DNS_entry* entry, int indent)
{
int ret = WOLFSSL_SUCCESS;
int nameCount = 0;
char scratch[MAX_WIDTH];
int len;
if (bio == NULL || entry == NULL) {
return WOLFSSL_FAILURE;
}
len = XSNPRINTF(scratch, MAX_WIDTH, "%*s", indent, "");
if (len >= MAX_WIDTH) {
return WOLFSSL_FAILURE;
}
if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch)) <= 0) {
return WOLFSSL_FAILURE;
}
while (entry != NULL) {
++nameCount;
if (nameCount > 1) {
if (wolfSSL_BIO_write(bio, ", ", 2) <= 0) {
ret = WOLFSSL_FAILURE;
break;
}
}
if (entry->type == ASN_DNS_TYPE) {
len = XSNPRINTF(scratch, MAX_WIDTH, "DNS:%s", entry->name);
if (len >= MAX_WIDTH) {
ret = WOLFSSL_FAILURE;
break;
}
}
#if defined(OPENSSL_ALL) || defined(WOLFSSL_IP_ALT_NAME)
else if (entry->type == ASN_IP_TYPE) {
len = XSNPRINTF(scratch, MAX_WIDTH, "IP Address:%s",
entry->ipString);
if (len >= MAX_WIDTH) {
ret = WOLFSSL_FAILURE;
break;
}
}
#endif /* OPENSSL_ALL || WOLFSSL_IP_ALT_NAME */
else if (entry->type == ASN_RFC822_TYPE) {
len = XSNPRINTF(scratch, MAX_WIDTH, "email:%s",
entry->name);
if (len >= MAX_WIDTH) {
ret = WOLFSSL_FAILURE;
break;
}
}
else if (entry->type == ASN_DIR_TYPE) {
len = X509PrintDirType(scratch, MAX_WIDTH, entry);
if (len >= MAX_WIDTH) {
ret = WOLFSSL_FAILURE;
break;
}
}
else if (entry->type == ASN_URI_TYPE) {
len = XSNPRINTF(scratch, MAX_WIDTH, "URI:%s",
entry->name);
if (len >= MAX_WIDTH) {
ret = WOLFSSL_FAILURE;
break;
}
}
#if defined(OPENSSL_ALL)
else if (entry->type == ASN_RID_TYPE) {
len = XSNPRINTF(scratch, MAX_WIDTH, "Registered ID:%s",
entry->ridString);
if (len >= MAX_WIDTH) {
ret = WOLFSSL_FAILURE;
break;
}
}
#endif
else if (entry->type == ASN_OTHER_TYPE) {
len = XSNPRINTF(scratch, MAX_WIDTH,
"othername <unsupported>");
if (len >= MAX_WIDTH) {
ret = WOLFSSL_FAILURE;
break;
}
}
else {
WOLFSSL_MSG("Bad alt name type.");
ret = WOLFSSL_FAILURE;
break;
}
if (wolfSSL_BIO_write(bio, scratch, (int)XSTRLEN(scratch))
<= 0) {
ret = WOLFSSL_FAILURE;
break;
}
entry = entry->next;
}
if (ret == WOLFSSL_SUCCESS && wolfSSL_BIO_write(bio, "\n", 1) <= 0) {
ret = WOLFSSL_FAILURE;
}
return ret;
}
/* Sets buf pointer and len to raw Attribute buffer and buffer len
* in X509 struct.
*
* Returns WOLFSSL_SUCCESS on success.
* Returns BAD_FUNC_ARG if input pointers are null.
* */
WOLFSSL_API int wolfSSL_X509_ACERT_get_attr_buf(const WOLFSSL_X509_ACERT* x509,
const byte ** rawAttr,
word32 * rawAttrLen)
{
if (x509 == NULL || rawAttr == NULL || rawAttrLen == NULL) {
return BAD_FUNC_ARG;
}
*rawAttr = x509->rawAttr;
*rawAttrLen = x509->rawAttrLen;
return WOLFSSL_SUCCESS;
}
#endif /* if WOLFSSL_ACERT*/
static int X509PrintSubjAltName(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
int indent)
{
@ -6156,6 +6398,70 @@ static int X509PrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent)
return WOLFSSL_SUCCESS;
}
#ifndef NO_ASN_TIME
static int X509PrintValidity(WOLFSSL_BIO* bio, WOLFSSL_ASN1_TIME * notBefore,
WOLFSSL_ASN1_TIME * notAfter, int indent)
{
char tmp[80];
(void) indent;
if (wolfSSL_BIO_write(bio, " Validity\n",
(int)XSTRLEN(" Validity\n")) <= 0) {
return WOLFSSL_FAILURE;
}
if (wolfSSL_BIO_write(bio, " Not Before: ",
(int)XSTRLEN(" Not Before: ")) <= 0) {
return WOLFSSL_FAILURE;
}
if (notBefore->length > 0) {
if (GetTimeString(notBefore->data, ASN_UTC_TIME,
tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
if (GetTimeString(notBefore->data, ASN_GENERALIZED_TIME,
tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Error getting not before date");
return WOLFSSL_FAILURE;
}
}
}
else {
XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
}
tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE;
}
if (wolfSSL_BIO_write(bio, "\n Not After : ",
(int)XSTRLEN("\n Not After : ")) <= 0) {
return WOLFSSL_FAILURE;
}
if (notAfter->length > 0) {
if (GetTimeString(notAfter->data, ASN_UTC_TIME,
tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
if (GetTimeString(notAfter->data, ASN_GENERALIZED_TIME,
tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Error getting not after date");
return WOLFSSL_FAILURE;
}
}
}
else {
XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
}
tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE;
}
if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
}
#endif /* ifndef NO_ASN_TIME */
/* iterate through certificate extensions printing them out in human readable
* form
* return WOLFSSL_SUCCESS on success
@ -6872,65 +7178,13 @@ int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509,
return WOLFSSL_FAILURE;
}
#ifndef NO_ASN_TIME
#ifndef NO_ASN_TIME
/* print validity */
{
char tmp[80];
if (wolfSSL_BIO_write(bio, " Validity\n",
(int)XSTRLEN(" Validity\n")) <= 0) {
return WOLFSSL_FAILURE;
}
if (wolfSSL_BIO_write(bio, " Not Before: ",
(int)XSTRLEN(" Not Before: ")) <= 0) {
return WOLFSSL_FAILURE;
}
if (x509->notBefore.length > 0) {
if (GetTimeString(x509->notBefore.data, ASN_UTC_TIME,
tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
if (GetTimeString(x509->notBefore.data, ASN_GENERALIZED_TIME,
tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Error getting not before date");
return WOLFSSL_FAILURE;
}
}
}
else {
XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
}
tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE;
}
if (wolfSSL_BIO_write(bio, "\n Not After : ",
(int)XSTRLEN("\n Not After : ")) <= 0) {
return WOLFSSL_FAILURE;
}
if (x509->notAfter.length > 0) {
if (GetTimeString(x509->notAfter.data, ASN_UTC_TIME,
tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
if (GetTimeString(x509->notAfter.data, ASN_GENERALIZED_TIME,
tmp, sizeof(tmp)) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("Error getting not after date");
return WOLFSSL_FAILURE;
}
}
}
else {
XSTRNCPY(tmp, "Not Set", sizeof(tmp)-1);
}
tmp[sizeof(tmp) - 1] = '\0'; /* make sure null terminated */
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE;
}
if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
return WOLFSSL_FAILURE;
}
if (X509PrintValidity(bio, &x509->notBefore, &x509->notAfter, 8)
!= WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
#endif
#endif /* NO_ASN_TIME */
/* print subject */
if (X509PrintName(bio, wolfSSL_X509_get_subject_name(x509), subjType, 8)
@ -6965,6 +7219,438 @@ int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509)
return wolfSSL_X509_print_ex(bio, x509, 0, 0);
}
#if defined(WOLFSSL_ACERT)
WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_load_certificate_buffer(
const unsigned char* buf, int sz, int format)
{
int ret = 0;
WOLFSSL_X509_ACERT * x509 = NULL;
DerBuffer * der = NULL;
#ifdef WOLFSSL_SMALL_STACK
DecodedAcert * acert = NULL;
#else
DecodedAcert acert[1];
#endif
WOLFSSL_ENTER("wolfSSL_X509_ACERT_load_certificate_buffer");
if (format == WOLFSSL_FILETYPE_PEM) {
#ifdef WOLFSSL_PEM_TO_DER
ret = PemToDer(buf, sz, ACERT_TYPE, &der, NULL, NULL, NULL);
if (ret != 0 || der == NULL || der->buffer == NULL) {
WOLFSSL_ERROR(ret);
if (der != NULL) {
FreeDer(&der);
}
return NULL;
}
#else
WOLFSSL_ERROR(NOT_COMPILED_IN);
return NULL;
#endif
}
else {
ret = AllocDer(&der, (word32)sz, ACERT_TYPE, NULL);
if (ret != 0 || der == NULL || der->buffer == NULL) {
WOLFSSL_ERROR(ret);
return NULL;
}
XMEMCPY(der->buffer, buf, sz);
}
#ifdef WOLFSSL_SMALL_STACK
acert = (DecodedAcert*)XMALLOC(sizeof(DecodedAcert), NULL,
DYNAMIC_TYPE_TMP_BUFFER);
if (acert == NULL) {
WOLFSSL_ERROR(MEMORY_ERROR);
FreeDer(&der);
return NULL;
}
#endif
InitDecodedAcert(acert, der->buffer, der->length, NULL);
ret = ParseX509Acert(acert, VERIFY_SKIP_DATE);
if (ret == 0) {
x509 = (WOLFSSL_X509_ACERT*)XMALLOC(sizeof(WOLFSSL_X509_ACERT), NULL,
DYNAMIC_TYPE_X509_ACERT);
if (x509 != NULL) {
wolfSSL_X509_ACERT_init(x509, NULL);
ret = CopyDecodedAcertToX509(x509, acert);
if (ret != 0) {
wolfSSL_X509_ACERT_free(x509);
x509 = NULL;
}
}
else {
ret = MEMORY_ERROR;
}
}
FreeDecodedAcert(acert);
#ifdef WOLFSSL_SMALL_STACK
XFREE(acert, NULL, DYNAMIC_TYPE_DCERT);
#endif
FreeDer(&der);
if (ret != 0) {
WOLFSSL_ERROR(ret);
}
return x509;
}
void wolfSSL_X509_ACERT_init(WOLFSSL_X509_ACERT * x509, void* heap)
{
if (x509 == NULL) {
WOLFSSL_MSG("error: InitX509Acert: null parameter");
return;
}
XMEMSET(x509, 0, sizeof(*x509));
x509->heap = heap;
}
void wolfSSL_X509_ACERT_free(WOLFSSL_X509_ACERT* x509)
{
if (x509 == NULL) {
WOLFSSL_MSG("error: wolfSSL_X509_ACERT_free: null parameter");
return;
}
/* Free holder and att cert issuer structures. */
if (x509->holderIssuerName) {
FreeAltNames(x509->holderIssuerName, x509->heap);
x509->holderIssuerName = NULL;
}
if (x509->AttCertIssuerName) {
FreeAltNames(x509->AttCertIssuerName, x509->heap);
x509->AttCertIssuerName = NULL;
}
if (x509->rawAttr != NULL) {
XFREE(x509->rawAttr, x509->heap, DYNAMIC_TYPE_X509_EXT);
x509->rawAttr = NULL;
x509->rawAttrLen = 0;
}
/* Free derCert source and signature buffer. */
FreeDer(&x509->derCert);
if (x509->sig.buffer != NULL) {
XFREE(x509->sig.buffer, x509->heap, DYNAMIC_TYPE_SIGNATURE);
x509->sig.buffer = NULL;
}
/* Finally memset and free x509 acert structure. */
XMEMSET(x509, 0, sizeof(*x509));
XFREE(x509, x509->heap, NULL);
return;
}
long wolfSSL_X509_ACERT_get_version(const WOLFSSL_X509_ACERT* x509)
{
int version = 0;
if (x509 == NULL) {
return 0L;
}
version = x509->version;
return version != 0 ? (long)version - 1L : 0L;
}
int wolfSSL_X509_ACERT_version(WOLFSSL_X509_ACERT* x509)
{
if (x509 == NULL) {
return 0;
}
return x509->version;
}
/* Retrieve sig NID from an ACERT.
*
* returns NID on success
* returns 0 on failure
*/
int wolfSSL_X509_ACERT_get_signature_nid(const WOLFSSL_X509_ACERT *x509)
{
if (x509 == NULL) {
return 0;
}
return oid2nid((word32)x509->sigOID, oidSigType);
}
/* Retrieve the signature from an ACERT.
*
* @param [in] x509 the x509 attribute certificate
* @param [in, out] buf the signature buffer pointer
* @param [in, out] bufSz the signature buffer size pointer
*
* buf may be null, but bufSz is required. On success, sets
* bufSz pointer to signature length, and copies signature
* to buf if provided.
*
* Returns WWOLFSSL_FATAL_ERROR if bufSz is null or too small.
* Returns WOLFSSL_SUCCESS on success.
*/
int wolfSSL_X509_ACERT_get_signature(WOLFSSL_X509_ACERT* x509,
unsigned char* buf, int* bufSz)
{
WOLFSSL_ENTER("wolfSSL_X509_ACERT_get_signature");
if (x509 == NULL || bufSz == NULL) {
return WOLFSSL_FATAL_ERROR;
}
/* If buf array is provided, it must be long enough. */
if (buf != NULL && *bufSz < (int)x509->sig.length) {
return WOLFSSL_FATAL_ERROR;
}
if (buf != NULL) {
/* Copy in buffer if provided. */
XMEMCPY(buf, x509->sig.buffer, x509->sig.length);
}
*bufSz = (int)x509->sig.length;
return WOLFSSL_SUCCESS;
}
static int X509AcertPrintSignature(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509,
int algOnly, int indent)
{
int sigSz = 0;
if (wolfSSL_X509_ACERT_get_signature(x509, NULL, &sigSz) <= 0) {
return WOLFSSL_FAILURE;
}
if (sigSz > 0) {
unsigned char* sig;
int sigNid;
sigNid = wolfSSL_X509_ACERT_get_signature_nid(x509);
if (sigNid <= 0) {
return WOLFSSL_FAILURE;
}
sig = (unsigned char*)XMALLOC(sigSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (sig == NULL) {
return WOLFSSL_FAILURE;
}
if (wolfSSL_X509_ACERT_get_signature(x509, sig, &sigSz) <= 0) {
XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_FAILURE;
}
if (X509PrintSignature_ex(bio, sig, sigSz, sigNid, algOnly, indent)
!= WOLFSSL_SUCCESS) {
XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return WOLFSSL_FAILURE;
}
if (sig != NULL) {
XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
}
return WOLFSSL_SUCCESS;
}
/* Retrieve the serial number from an ACERT.
*
* @param [in] x509 the x509 attribute certificate
* @param [in, out] buf the serial number buffer pointer
* @param [in, out] bufSz the serial number buffer size pointer
*
* buf may be null, but bufSz is required. On success, sets
* bufSz pointer to signature length, and copies signature
* to buf if provided.
*
* Returns WWOLFSSL_FATAL_ERROR if bufSz is null or too small.
* Returns WOLFSSL_SUCCESS on success.
*/
int wolfSSL_X509_ACERT_get_serial_number(WOLFSSL_X509_ACERT* x509,
byte* buf, int* bufSz)
{
WOLFSSL_ENTER("wolfSSL_X509_ACERT_get_serial_number");
if (x509 == NULL || bufSz == NULL) {
WOLFSSL_MSG("error: null argument passed in");
return BAD_FUNC_ARG;
}
if (buf != NULL) {
if (*bufSz < x509->serialSz) {
WOLFSSL_MSG("error: serial buffer too small");
return BUFFER_E;
}
XMEMCPY(buf, x509->serial, x509->serialSz);
}
*bufSz = x509->serialSz;
return WOLFSSL_SUCCESS;
}
static int X509AcertPrintSerial(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509,
int indent)
{
unsigned char serial[32];
int sz = sizeof(serial);
XMEMSET(serial, 0, sz);
if (wolfSSL_X509_ACERT_get_serial_number(x509, serial, &sz)
== WOLFSSL_SUCCESS) {
X509PrintSerial_ex(bio, serial, sz, 1, indent);
}
return WOLFSSL_SUCCESS;
}
int wolfSSL_X509_ACERT_print(WOLFSSL_BIO* bio, WOLFSSL_X509_ACERT* x509)
{
const char * hdr = "Attribute Certificate:\n";
const char * data_hdr = " Data:\n";
const char * holder_hdr = " Holder:\n";
const char * holder_issuer_hdr = " Issuer:";
const char * holder_name_hdr = " Name:";
const char * attcert_issuer_hdr = " Issuer:";
if (bio == NULL || x509 == NULL) {
return WOLFSSL_FAILURE;
}
/* print acert header */
if (wolfSSL_BIO_write(bio, hdr, (int)XSTRLEN(hdr)) <= 0) {
return WOLFSSL_FAILURE;
}
/* print data header */
if (wolfSSL_BIO_write(bio, data_hdr, (int)XSTRLEN(data_hdr)) <= 0) {
return WOLFSSL_FAILURE;
}
/* print version of cert */
if (X509PrintVersion(bio, wolfSSL_X509_ACERT_version(x509), 8)
!= WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
/* print serial number out */
if (X509AcertPrintSerial(bio, x509, 8) != WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
/* print holder field */
if (wolfSSL_BIO_write(bio, holder_hdr, (int)XSTRLEN(holder_hdr)) <= 0) {
return WOLFSSL_FAILURE;
}
if (x509->holderEntityName != NULL) {
/* print issuer header */
if (wolfSSL_BIO_write(bio, holder_name_hdr,
(int)XSTRLEN(holder_name_hdr)) <= 0) {
return WOLFSSL_FAILURE;
}
if (X509_ACERT_print_name_entry(bio, x509->holderEntityName, 1)
!= WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
}
if (x509->holderIssuerName != NULL) {
/* print issuer header */
if (wolfSSL_BIO_write(bio, holder_issuer_hdr,
(int)XSTRLEN(holder_issuer_hdr)) <= 0) {
return WOLFSSL_FAILURE;
}
if (X509_ACERT_print_name_entry(bio, x509->holderIssuerName, 1)
!= WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
}
if (x509->holderSerialSz > 0) {
X509PrintSerial_ex(bio, x509->holderSerial, x509->holderSerialSz,
1, 12);
}
/* print issuer header */
if (wolfSSL_BIO_write(bio, attcert_issuer_hdr,
(int)XSTRLEN(attcert_issuer_hdr)) <= 0) {
return WOLFSSL_FAILURE;
}
if (x509->AttCertIssuerName != NULL) {
if (X509_ACERT_print_name_entry(bio, x509->AttCertIssuerName, 1)
!= WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
}
else {
const char * msg = " Issuer type not supported.\n";
if (wolfSSL_BIO_write(bio, msg, (int)XSTRLEN(msg)) <= 0) {
return WOLFSSL_FAILURE;
}
}
#ifndef NO_ASN_TIME
/* print validity */
if (X509PrintValidity(bio, &x509->notBefore, &x509->notAfter, 8)
!= WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
#endif /* NO_ASN_TIME */
/* print raw attributes */
if (x509->rawAttr && x509->rawAttrLen > 0) {
char attr_hdr[128]; /* buffer for XSNPRINTF */
if (XSNPRINTF(attr_hdr, 128, "%*s%s: %d bytes\n", 8, "",
"Attributes", x509->rawAttrLen) >= 128) {
return WOLFSSL_FAILURE;
}
if (wolfSSL_BIO_write(bio, attr_hdr, (int)XSTRLEN(attr_hdr)) <= 0) {
return WOLFSSL_FAILURE;
}
}
/* print out sig algo and signature */
if (X509AcertPrintSignature(bio, x509, 0, 8) != WOLFSSL_SUCCESS) {
return WOLFSSL_FAILURE;
}
/* done with print out */
if (wolfSSL_BIO_write(bio, "\n\0", (int)XSTRLEN("\n\0")) <= 0) {
return WOLFSSL_FAILURE;
}
return WOLFSSL_SUCCESS;
}
#endif /* WOLFSSL_ACERT */
#ifndef NO_FILESYSTEM
int wolfSSL_X509_print_fp(XFILE fp, WOLFSSL_X509 *x509)
{
@ -7699,6 +8385,95 @@ int wolfSSL_X509_REQ_verify(WOLFSSL_X509* x509, WOLFSSL_EVP_PKEY* pkey)
}
#endif /* WOLFSSL_CERT_REQ */
#if defined(WOLFSSL_ACERT)
#ifndef NO_WOLFSSL_STUB
WOLFSSL_API int wolfSSL_X509_ACERT_sign(WOLFSSL_X509_ACERT * x509,
WOLFSSL_EVP_PKEY * pkey,
const WOLFSSL_EVP_MD * md)
{
WOLFSSL_STUB("X509_ACERT_sign");
(void) x509;
(void) pkey;
(void) md;
return WOLFSSL_NOT_IMPLEMENTED;
}
#endif /* NO_WOLFSSL_STUB */
/* Helper function for ACERT_verify.
*
* @param [in] x509 the x509 attribute certificate
* @param [in, out] outSz the x509 der length
*
* @return der buffer on success
* @return NULL on error
* */
static const byte* acert_get_der(WOLFSSL_X509_ACERT * x509, int* outSz)
{
if (x509 == NULL || x509->derCert == NULL || outSz == NULL) {
return NULL;
}
*outSz = (int)x509->derCert->length;
return x509->derCert->buffer;
}
/* Given an X509_ACERT and EVP_PKEY, verify the acert's signature.
*
* @param [in] x509 the x509 attribute certificate
* @param [in] pkey the evp_pkey
*
* @return WOLFSSL_SUCCESS on verify success
* @return < 0 on error
* */
int wolfSSL_X509_ACERT_verify(WOLFSSL_X509_ACERT* x509, WOLFSSL_EVP_PKEY* pkey)
{
int ret = 0;
const byte * der = NULL;
int derSz = 0;
int pkey_type;
if (x509 == NULL || pkey == NULL) {
WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: bad arg");
return WOLFSSL_FATAL_ERROR;
}
WOLFSSL_ENTER("wolfSSL_X509_ACERT_verify");
der = acert_get_der(x509, &derSz);
if (der == NULL || derSz <= 0) {
WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: get der failed");
return WOLFSSL_FATAL_ERROR;
}
switch (pkey->type) {
case EVP_PKEY_RSA:
pkey_type = RSAk;
break;
case EVP_PKEY_EC:
pkey_type = ECDSAk;
break;
case EVP_PKEY_DSA:
pkey_type = DSAk;
break;
default:
WOLFSSL_MSG("error: wolfSSL_X509_ACERT_verify: unknown pkey type");
return WOLFSSL_FATAL_ERROR;
}
ret = VerifyX509Acert(der, (word32)derSz,
(const byte *)pkey->pkey.ptr, pkey->pkey_sz,
pkey_type, x509->heap);
return ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
}
#endif /* WOLFSSL_ACERT */
#if !defined(NO_FILESYSTEM)
static void *wolfSSL_d2i_X509_fp_ex(XFILE file, void **x509, int type)
{
@ -11391,6 +12166,63 @@ cleanup:
}
#if defined(WOLFSSL_ACERT)
WOLFSSL_X509_ACERT *wolfSSL_PEM_read_bio_X509_ACERT(WOLFSSL_BIO *bp,
WOLFSSL_X509_ACERT **x,
wc_pem_password_cb *cb,
void *u)
{
WOLFSSL_X509_ACERT* x509 = NULL;
#if defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)
unsigned char * pem = NULL;
int pemSz;
WOLFSSL_ENTER("wolfSSL_PEM_read_bio_X509_ACERT");
if (bp == NULL) {
WOLFSSL_LEAVE("wolfSSL_PEM_read_bio_X509_ACERT", BAD_FUNC_ARG);
return NULL;
}
if ((pemSz = wolfSSL_BIO_get_len(bp)) <= 0) {
/* No certificate in buffer */
WOLFSSL_ERROR(ASN_NO_PEM_HEADER);
return NULL;
}
pem = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM);
if (pem == NULL) {
return NULL;
}
XMEMSET(pem, 0, pemSz);
if (wolfSSL_BIO_read(bp, pem, pemSz) != pemSz) {
XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
return NULL;
}
x509 = wolfSSL_X509_ACERT_load_certificate_buffer(pem, pemSz,
WOLFSSL_FILETYPE_PEM);
if (x != NULL) {
*x = x509;
}
XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
#endif /* WOLFSSL_PEM_TO_DER || WOLFSSL_DER_TO_PEM */
(void)bp;
(void)x;
(void)cb;
(void)u;
return x509;
}
#endif /* WOLFSSL_ACERT */
WOLFSSL_X509 *wolfSSL_PEM_read_bio_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x,
wc_pem_password_cb *cb, void *u)
{

View File

@ -13488,6 +13488,272 @@ static int test_wolfSSL_X509_verify(void)
return EXPECT_RESULT();
}
#if defined(WOLFSSL_ACERT) && !defined(NO_CERTS) && !defined(NO_RSA) && \
!defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
/* Given acert file and its pubkey file, read them and then
* attempt to verify signed acert.
*
* If expect_pass is true, then verification should pass.
* If expect_pass is false, then verification should fail.
* */
static int do_acert_verify_test(const char * acert_file,
const char * pkey_file,
size_t expect_pass)
{
X509_ACERT * x509 = NULL;
EVP_PKEY * pkey = NULL;
BIO * bp = NULL;
int verify_rc = 0;
/* First read the attribute certificate. */
bp = BIO_new_file(acert_file, "r");
if (bp == NULL) {
return -1;
}
x509 = PEM_read_bio_X509_ACERT(bp, NULL, NULL, NULL);
BIO_free(bp);
bp = NULL;
if (x509 == NULL) {
return -1;
}
/* Next read the associated pub key. */
bp = BIO_new_file(pkey_file, "r");
if (bp == NULL) {
X509_ACERT_free(x509);
x509 = NULL;
return -1;
}
pkey = PEM_read_bio_PUBKEY(bp, &pkey, NULL, NULL);
BIO_free(bp);
bp = NULL;
if (pkey == NULL) {
X509_ACERT_free(x509);
x509 = NULL;
return -1;
}
/* Finally, do verification. */
verify_rc = X509_ACERT_verify(x509, pkey);
X509_ACERT_free(x509);
x509 = NULL;
EVP_PKEY_free(pkey);
pkey = NULL;
if (expect_pass && verify_rc != 1) {
return -1;
}
if (!expect_pass && verify_rc == 1) {
return -1;
}
return 0;
}
#endif
static int test_wolfSSL_X509_ACERT_verify(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_ACERT) && !defined(NO_CERTS) && !defined(NO_RSA) && \
defined(WC_RSA_PSS) && !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
/* Walk over list of signed ACERTs and their pubkeys.
* All should load and pass verification. */
const char * acerts[4] = {"certs/acert/acert.pem",
"certs/acert/acert_ietf.pem",
"certs/acert/rsa_pss/acert.pem",
"certs/acert/rsa_pss/acert_ietf.pem"};
const char * pkeys[4] = {"certs/acert/acert_pubkey.pem",
"certs/acert/acert_ietf_pubkey.pem",
"certs/acert/rsa_pss/acert_pubkey.pem",
"certs/acert/rsa_pss/acert_ietf_pubkey.pem"};
int rc = 0;
size_t i = 0;
size_t j = 0;
for (i = 0; i < 4; ++i) {
for (j = i; j < 4; ++j) {
rc = do_acert_verify_test(acerts[i], pkeys[j], i == j);
if (rc) {
fprintf(stderr, "error: %s: i = %zu, j = %zu, rc = %d\n",
"do_acert_verify_test", i, j, rc);
break;
}
}
if (rc) { break; }
}
ExpectIntEQ(rc, 0);
#endif
return EXPECT_RESULT();
}
static int test_wolfSSL_X509_ACERT_misc_api(void)
{
EXPECT_DECLS;
#if defined(WOLFSSL_ACERT) && !defined(NO_CERTS) && !defined(NO_RSA) && \
!defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
const char * acerts[4] = {"certs/acert/acert.pem",
"certs/acert/acert_ietf.pem",
"certs/acert/rsa_pss/acert.pem",
"certs/acert/rsa_pss/acert_ietf.pem"};
int rc = 0;
X509_ACERT * x509 = NULL;
BIO * bp = NULL;
long ver_long = 0;
int ver = 0;
int nid = 0;
const byte * raw_attr = NULL;
word32 attr_len = 0;
size_t i = 0;
int buf_len = 0;
byte ietf_serial[] = {0x03, 0xb5, 0x90, 0x59, 0x02,
0xa2, 0xaa, 0xb5, 0x40, 0x21,
0x44, 0xb8, 0x2c, 0x4f, 0xd9,
0x80, 0x1b, 0x5f, 0x57, 0xc2};
for (i = 0; i < 4; ++i) {
const char * acert_file = acerts[i];
int is_rsa_pss = 0;
int is_ietf_acert = 0;
byte serial[64];
int serial_len = sizeof(serial);
XMEMSET(serial, 0, sizeof(serial));
is_rsa_pss = XSTRSTR(acert_file, "rsa_pss") != NULL ? 1 : 0;
is_ietf_acert = XSTRSTR(acert_file, "ietf.pem") != NULL ? 1 : 0;
/* First read the attribute certificate. */
bp = BIO_new_file(acert_file, "r");
ExpectNotNull(bp);
x509 = PEM_read_bio_X509_ACERT(bp, NULL, NULL, NULL);
ExpectNotNull(x509);
/* We're done with the bio for now. */
if (bp != NULL) {
BIO_free(bp);
bp = NULL;
}
/* Check version and signature NID. */
ver_long = X509_ACERT_get_version(x509);
ExpectIntEQ(ver_long, 1);
ver = wolfSSL_X509_ACERT_version(x509);
ExpectIntEQ(ver, 2);
nid = X509_ACERT_get_signature_nid(x509);
if (is_rsa_pss) {
ExpectIntEQ(nid, NID_rsassaPss);
}
else {
ExpectIntEQ(nid, NID_sha256WithRSAEncryption);
}
/* Get the serial number buffer.
* The ietf acert example has a 20 byte serial number. */
rc = wolfSSL_X509_ACERT_get_serial_number(x509, serial, &serial_len);
ExpectIntEQ(rc, SSL_SUCCESS);
if (is_ietf_acert) {
ExpectIntEQ(serial_len, 20);
ExpectIntEQ(XMEMCMP(serial, ietf_serial, sizeof(ietf_serial)), 0);
}
else {
ExpectIntEQ(serial_len, 1);
ExpectTrue(serial[0] == 0x01);
}
/* Repeat the same but with null serial buffer. This is ok. */
rc = wolfSSL_X509_ACERT_get_serial_number(x509, NULL, &serial_len);
ExpectIntEQ(rc, SSL_SUCCESS);
if (is_ietf_acert) {
ExpectIntEQ(serial_len, 20);
}
else {
ExpectIntEQ(serial_len, 1);
ExpectTrue(serial[0] == 0x01);
}
/* Get the attributes buffer. */
rc = wolfSSL_X509_ACERT_get_attr_buf(x509, &raw_attr, &attr_len);
ExpectIntEQ(rc, SSL_SUCCESS);
if (is_ietf_acert) {
/* This cert has a 65 byte attributes field. */
ExpectNotNull(raw_attr);
ExpectIntEQ(attr_len, 65);
}
else {
/* This cert has a 237 byte attributes field. */
ExpectNotNull(raw_attr);
ExpectIntEQ(attr_len, 237);
}
/* Test printing acert to memory bio. */
ExpectNotNull(bp = BIO_new(BIO_s_mem()));
rc = X509_ACERT_print(bp, x509);
ExpectIntEQ(rc, SSL_SUCCESS);
/* Now do a bunch of invalid stuff with partially valid inputs. */
rc = wolfSSL_X509_ACERT_get_attr_buf(x509, &raw_attr, NULL);
ExpectIntEQ(rc, BAD_FUNC_ARG);
rc = wolfSSL_X509_ACERT_get_attr_buf(x509, NULL, &attr_len);
ExpectIntEQ(rc, BAD_FUNC_ARG);
rc = wolfSSL_X509_ACERT_get_attr_buf(NULL, &raw_attr, &attr_len);
ExpectIntEQ(rc, BAD_FUNC_ARG);
ver_long = X509_ACERT_get_version(NULL);
ExpectIntEQ(ver_long, 0);
ver = wolfSSL_X509_ACERT_version(NULL);
ExpectIntEQ(ver, 0);
rc = wolfSSL_X509_ACERT_get_signature(x509, NULL, NULL);
ExpectIntEQ(rc, WOLFSSL_FATAL_ERROR);
rc = wolfSSL_X509_ACERT_get_signature(x509, NULL, &buf_len);
ExpectIntEQ(rc, SSL_SUCCESS);
ExpectIntEQ(buf_len, 256);
rc = wolfSSL_X509_ACERT_get_serial_number(x509, serial, NULL);
ExpectIntEQ(rc, BAD_FUNC_ARG);
rc = X509_ACERT_print(bp, NULL);
ExpectIntEQ(rc, WOLFSSL_FAILURE);
rc = X509_ACERT_print(NULL, x509);
ExpectIntEQ(rc, WOLFSSL_FAILURE);
/* Finally free the acert and bio, we're done with them. */
if (x509 != NULL) {
X509_ACERT_free(x509);
x509 = NULL;
}
if (bp != NULL) {
BIO_free(bp);
bp = NULL;
}
}
#endif
return EXPECT_RESULT();
}
#if !defined(NO_DH) && !defined(NO_AES) && defined(WOLFSSL_CERT_GEN) && \
defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES) && \
@ -95342,6 +95608,10 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wolfSSL_X509_max_name_constraints),
TEST_DECL(test_wolfSSL_make_cert),
/* X509 ACERT tests */
TEST_DECL(test_wolfSSL_X509_ACERT_verify),
TEST_DECL(test_wolfSSL_X509_ACERT_misc_api),
#ifndef NO_BIO
TEST_DECL(test_wolfSSL_X509_INFO_multiple_info),
TEST_DECL(test_wolfSSL_X509_INFO),

File diff suppressed because it is too large Load Diff

View File

@ -5317,6 +5317,29 @@ struct WOLFSSL_X509 {
#endif /* WOLFSSL_DUAL_ALG_CERTS */
};
#if defined(WOLFSSL_ACERT)
struct WOLFSSL_X509_ACERT {
int version;
int serialSz;
byte serial[EXTERNAL_SERIAL_SIZE];
WOLFSSL_ASN1_TIME notBefore;
WOLFSSL_ASN1_TIME notAfter;
buffer sig;
int sigOID;
#ifndef NO_CERTS
DerBuffer * derCert;
#endif
void* heap;
/* copy of raw Attributes field from */
byte holderSerial[EXTERNAL_SERIAL_SIZE];
int holderSerialSz;
DNS_entry * holderEntityName; /* Holder entityName from ACERT */
DNS_entry * holderIssuerName; /* issuerName from ACERT */
DNS_entry * AttCertIssuerName; /* AttCertIssuer name from ACERT */
byte * rawAttr;
word32 rawAttrLen;
};
#endif /* WOLFSSL_ACERT */
/* record layer header for PlainText, Compressed, and CipherText */
typedef struct RecordLayerHeader {
@ -6595,6 +6618,12 @@ WOLFSSL_LOCAL enum wc_HashType HashAlgoToType(int hashAlgo);
DecodedCert* dCert);
#endif
#if defined(WOLFSSL_ACERT)
WOLFSSL_LOCAL int CopyDecodedAcertToX509(WOLFSSL_X509_ACERT* x509,
DecodedAcert* dAcert);
#endif /* WOLFSSL_ACERT */
#ifndef MAX_CIPHER_NAME
#define MAX_CIPHER_NAME 50
#endif

View File

@ -100,6 +100,7 @@ typedef WOLFSSL_CIPHER SSL_CIPHER;
typedef WOLFSSL_X509_LOOKUP X509_LOOKUP;
typedef WOLFSSL_X509_LOOKUP_METHOD X509_LOOKUP_METHOD;
typedef WOLFSSL_X509_CRL X509_CRL;
typedef WOLFSSL_X509_ACERT X509_ACERT;
typedef WOLFSSL_X509_EXTENSION X509_EXTENSION;
typedef WOLFSSL_X509_PUBKEY X509_PUBKEY;
typedef WOLFSSL_X509_ALGOR X509_ALGOR;
@ -745,6 +746,14 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
#define X509_CRL_get_version wolfSSL_X509_CRL_version
#define X509_load_crl_file wolfSSL_X509_load_crl_file
#define X509_ACERT_free wolfSSL_X509_ACERT_free
#define X509_ACERT_get_version wolfSSL_X509_ACERT_get_version
#define X509_ACERT_get_signature_nid wolfSSL_X509_ACERT_get_signature_nid
#define X509_ACERT_print wolfSSL_X509_ACERT_print
#define X509_ACERT_verify wolfSSL_X509_ACERT_verify
#define X509_ACERT_sign wolfSSL_X509_ACERT_sign
#define PEM_read_bio_X509_ACERT wolfSSL_PEM_read_bio_X509_ACERT
#define X509_get_X509_PUBKEY wolfSSL_X509_get_X509_PUBKEY
#define X509_REQ_get_X509_PUBKEY wolfSSL_X509_get_X509_PUBKEY
#define X509_get0_tbs_sigalg wolfSSL_X509_get0_tbs_sigalg

View File

@ -149,6 +149,7 @@ typedef struct WOLFSSL_CTX WOLFSSL_CTX;
typedef struct WOLFSSL_STACK WOLFSSL_STACK;
typedef struct WOLFSSL_X509 WOLFSSL_X509;
typedef struct WOLFSSL_X509_ACERT WOLFSSL_X509_ACERT;
typedef struct WOLFSSL_X509_NAME WOLFSSL_X509_NAME;
typedef struct WOLFSSL_X509_NAME_ENTRY WOLFSSL_X509_NAME_ENTRY;
typedef struct WOLFSSL_X509_PUBKEY WOLFSSL_X509_PUBKEY;
@ -2944,6 +2945,7 @@ WOLFSSL_API WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int
/* free X509 */
#define wolfSSL_FreeX509(x509) wolfSSL_X509_free((x509))
WOLFSSL_ABI WOLFSSL_API void wolfSSL_X509_free(WOLFSSL_X509* x509);
/* get index cert in PEM */
WOLFSSL_API int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx,
unsigned char* buf, int inLen, int* outLen);
@ -3003,6 +3005,37 @@ WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_X509_CRL_dup(const WOLFSSL_X509_CRL* crl);
WOLFSSL_API void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl);
#endif
#if defined(WOLFSSL_ACERT)
WOLFSSL_API void wolfSSL_X509_ACERT_init(WOLFSSL_X509_ACERT * x509,
void* heap);
WOLFSSL_API void wolfSSL_X509_ACERT_free(WOLFSSL_X509_ACERT* x509);
#ifndef NO_WOLFSSL_STUB
WOLFSSL_API int wolfSSL_X509_ACERT_sign(WOLFSSL_X509_ACERT * x509,
WOLFSSL_EVP_PKEY * pkey,
const WOLFSSL_EVP_MD * md);
#endif /* !NO_WOLFSSL_STUB */
WOLFSSL_API int wolfSSL_X509_ACERT_verify(WOLFSSL_X509_ACERT* x509,
WOLFSSL_EVP_PKEY* pkey);
WOLFSSL_API int wolfSSL_X509_ACERT_print(WOLFSSL_BIO* bio,
WOLFSSL_X509_ACERT* x509_acert);
WOLFSSL_API int wolfSSL_X509_ACERT_get_attr_buf(const WOLFSSL_X509_ACERT* x509,
const byte ** rawAttr,
word32 * rawAttrLen);
WOLFSSL_API int wolfSSL_X509_ACERT_get_serial_number(WOLFSSL_X509_ACERT* x509,
unsigned char* in,
int * inOutSz);
WOLFSSL_API int wolfSSL_X509_ACERT_version(WOLFSSL_X509_ACERT* x509);
WOLFSSL_API long wolfSSL_X509_ACERT_get_version(const WOLFSSL_X509_ACERT *x);
WOLFSSL_API int wolfSSL_X509_ACERT_get_signature_nid(const WOLFSSL_X509_ACERT* x);
WOLFSSL_API int wolfSSL_X509_ACERT_get_signature(WOLFSSL_X509_ACERT* x509,
unsigned char* buf,
int* bufSz);
WOLFSSL_API WOLFSSL_X509_ACERT * wolfSSL_PEM_read_bio_X509_ACERT(
WOLFSSL_BIO *bp, WOLFSSL_X509_ACERT **x, wc_pem_password_cb *cb, void *u);
WOLFSSL_API WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_load_certificate_buffer(
const unsigned char* buf, int sz, int format);
#endif
WOLFSSL_API
const WOLFSSL_ASN1_INTEGER* wolfSSL_X509_REVOKED_get0_serial_number(const
WOLFSSL_X509_REVOKED *rev);

View File

@ -2287,8 +2287,8 @@ WOLFSSL_LOCAL int SetShortInt(byte* input, word32* inOutIdx, word32 number,
word32 maxIdx);
WOLFSSL_LOCAL const char* GetSigName(int oid);
WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len,
word32 maxIdx);
WOLFSSL_ASN_API int GetLength(const byte* input, word32* inOutIdx, int* len,
word32 maxIdx);
WOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len,
word32 maxIdx, int check);
WOLFSSL_LOCAL int GetASNHeader(const byte* input, byte tag, word32* inOutIdx,
@ -2332,8 +2332,8 @@ WOLFSSL_LOCAL int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid,
word32 oidType, word32 maxIdx);
WOLFSSL_LOCAL int GetAlgoIdEx(const byte* input, word32* inOutIdx, word32* oid,
word32 oidType, word32 maxIdx, byte *absentParams);
WOLFSSL_LOCAL int GetASNTag(const byte* input, word32* idx, byte* tag,
word32 inputSz);
WOLFSSL_ASN_API int GetASNTag(const byte* input, word32* idx, byte* tag,
word32 inputSz);
WOLFSSL_LOCAL int GetASN_BitString(const byte* input, word32 idx, int length);
WOLFSSL_LOCAL word32 SetASNLength(word32 length, byte* output);
@ -2707,9 +2707,56 @@ WOLFSSL_LOCAL int ParseCRL(RevokedCert* rcert, DecodedCRL* dcrl,
const byte* buff, word32 sz, int verify, void* cm);
WOLFSSL_LOCAL void FreeDecodedCRL(DecodedCRL* dcrl);
#endif /* HAVE_CRL */
#if defined(WOLFSSL_ACERT)
/* Minimal structure for x509 attribute certificate (rfc 5755).
*
* The attributes field is not parsed, but is stored as raw buffer.
*
* */
struct DecodedAcert {
word32 certBegin; /* Offset to start of acert. */
word32 sigIndex; /* Offset to start of signature. */
word32 sigLength; /* Signature length. */
word32 signatureOID; /* Sum of algorithm object id. */
#ifdef WC_RSA_PSS
word32 sigParamsIndex; /* start of signature parameters */
word32 sigParamsLength; /* length of signature parameters */
#endif
const byte * signature; /* Not owned, points into raw acert. */
const byte * source; /* Byte buffer holding acert, NOT owned. */
word32 srcIdx; /* Current offset into buffer. */
word32 maxIdx; /* Max allowed offset. Set in init. */
void * heap; /* For user memory overrides. */
int version; /* attribute cert version. */
byte serial[EXTERNAL_SERIAL_SIZE]; /* Raw serial number. */
int serialSz;
const byte * beforeDate; /* Before and After dates. */
int beforeDateLen;
const byte * afterDate;
int afterDateLen;
byte holderSerial[EXTERNAL_SERIAL_SIZE];
int holderSerialSz;
DNS_entry * holderEntityName; /* Holder entityName from ACERT */
DNS_entry * holderIssuerName; /* Holder issuerName from ACERT */
DNS_entry * AttCertIssuerName; /* AttCertIssuer name from ACERT */
const byte * rawAttr; /* Not owned, points into raw acert. */
word32 rawAttrLen;
SignatureCtx sigCtx;
};
typedef struct DecodedAcert DecodedAcert;
WOLFSSL_LOCAL void InitDecodedAcert(DecodedAcert* acert,
const byte* source, word32 inSz,
void* heap);
WOLFSSL_LOCAL void FreeDecodedAcert(DecodedAcert * acert);
WOLFSSL_LOCAL int ParseX509Acert(DecodedAcert* cert, int verify);
WOLFSSL_LOCAL int VerifyX509Acert(const byte* cert, word32 certSz,
const byte* pubKey, word32 pubKeySz,
int pubKeyOID, void * heap);
#endif /* WOLFSSL_ACERT */
#ifdef __cplusplus
} /* extern "C" */

View File

@ -148,6 +148,7 @@ enum CertType {
CA_TYPE,
ECC_PRIVATEKEY_TYPE,
DSA_PRIVATEKEY_TYPE,
ACERT_TYPE,
CERTREQ_TYPE,
DSA_TYPE,
ECC_TYPE,

View File

@ -3189,6 +3189,10 @@ extern void uITRON4_free(void *p) ;
#error "Dual alg cert support requires the ASN.1 template feature."
#endif
#if defined(WOLFSSL_ACERT) && !defined(WOLFSSL_ASN_TEMPLATE)
#error "Attribute Certificate support requires the ASN.1 template feature."
#endif
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
#undef WOLFSSL_ASN_ALL
#define WOLFSSL_ASN_ALL
@ -3284,6 +3288,11 @@ extern void uITRON4_free(void *p) ;
/* Extended Key Usage */
#undef WOLFSSL_EKU_OID
#define WOLFSSL_EKU_OID
/* Attribute Certificate support */
#if defined(WOLFSSL_ASN_TEMPLATE) && !defined(WOLFSSL_ACERT)
#define WOLFSSL_ACERT
#endif
#endif
#if defined(OPENSSL_ALL) || defined(WOLFSSL_MYSQL_COMPATIBLE) || \

View File

@ -1097,6 +1097,7 @@ typedef struct w64wrapper {
DYNAMIC_TYPE_DEBUG_TAG = 100,
DYNAMIC_TYPE_LMS = 101,
DYNAMIC_TYPE_BIO = 102,
DYNAMIC_TYPE_X509_ACERT = 103,
DYNAMIC_TYPE_SNIFFER_SERVER = 1000,
DYNAMIC_TYPE_SNIFFER_SESSION = 1001,
DYNAMIC_TYPE_SNIFFER_PB = 1002,