Skip to content

Commit ef35e7a

Browse files
authored
Merge pull request wolfSSL#333 from padelsbach/padelsbach/crl-decode
Add CRL decode
2 parents b937eec + 34f3518 commit ef35e7a

11 files changed

Lines changed: 878 additions & 23 deletions

File tree

examples/certs/test/crl-decode.der

474 Bytes
Binary file not shown.

examples/certs/test/crl-decode.pem

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-----BEGIN X509 CRL-----
2+
MIIB1jCBvwIBATANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJVUzEQMA4GA1UE
3+
CAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjEVMBMGA1UECgwMd29sZlNTTCBJ
4+
bmMuMRkwFwYDVQQLDBBEZXZlbG9wbWVudCBUZXN0MRgwFgYDVQQDDA93b2xmU1NM
5+
IFRlc3QgQ0EXDTI2MDIxOTAwMzYyMloXDTM2MDIxNzAwMzYyMlqgDjAMMAoGA1Ud
6+
FAQDAgEBMA0GCSqGSIb3DQEBCwUAA4IBAQCvwOGtRd31ztiKj6SPIe3Oo0bW0MC+
7+
bBqd5oCpupUR9qEdV391PNT2F/h6P61asKJbj5ItPoFAKjOKmCFm6UvJp24ypxmr
8+
n3pbvjFH+ki77+3fyzvZmkbyQC5vrdb8X9dEvwk3/z98x9QB47d2zVyQLMG9ZEHT
9+
uTQXL9liz8V1q2BHy3V8/wwsPJhZTm3sViayixQA80YOtp1+7K08GnOhvAr78Vqd
10+
CvN4lY3GUkzgjt6n4gFSrsahIAyGb7hZ9opSQBAO/SMg1P6J85bYshTWSiD6aLCY
11+
uUxLGPkJSEKdqQph/vAr4JifZQIaIHY9oP4HmDHw8ChFlvz571YHyDLV
12+
-----END X509 CRL-----

examples/certs/update-certs.sh

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,62 @@ rm intermediate/ca-int-ecc-cert.pem.bak
148148
rm intermediate/server-int-cert.pem.bak
149149
rm intermediate/server-int-ecc-cert.pem.bak
150150

151+
# Generate test CRL (PEM and DER) for WolfSSLCRL decode testing.
152+
# Creates a self-signed CA, revokes a dummy serial, produces CRL in
153+
# both PEM and DER formats under test/.
154+
printf "\nGenerating test CRL for CRL decode testing...\n"
155+
TMP_DIR="$(mktemp -d)"
156+
157+
# CA key + self-signed cert
158+
openssl genrsa -out "${TMP_DIR}/crl-test-ca-key.pem" 2048 2>/dev/null
159+
openssl req -x509 -new -nodes \
160+
-key "${TMP_DIR}/crl-test-ca-key.pem" \
161+
-sha256 -days 3650 \
162+
-subj "/C=US/ST=Montana/L=Bozeman/O=wolfSSL Inc./OU=Development Test/CN=wolfSSL Test CA" \
163+
-out "${TMP_DIR}/crl-test-ca-cert.pem" 2>/dev/null
164+
165+
# CRL index / database files required by openssl ca
166+
touch "${TMP_DIR}/index.txt"
167+
echo "01" > "${TMP_DIR}/crlnumber"
168+
169+
cat > "${TMP_DIR}/openssl-ca.cnf" <<EOF
170+
[ ca ]
171+
default_ca = CA_default
172+
173+
[ CA_default ]
174+
database = ${TMP_DIR}/index.txt
175+
crlnumber = ${TMP_DIR}/crlnumber
176+
default_md = sha256
177+
default_crl_days = 3650
178+
179+
[ crl_ext ]
180+
authorityKeyIdentifier = keyid:always
181+
EOF
182+
183+
# Generate CRL with empty revocation list. Decode tests only need to parse
184+
# the CRL structure (issuer, signature, dates, etc.), not iterate entries.
185+
openssl ca -gencrl \
186+
-keyfile "${TMP_DIR}/crl-test-ca-key.pem" \
187+
-cert "${TMP_DIR}/crl-test-ca-cert.pem" \
188+
-config "${TMP_DIR}/openssl-ca.cnf" \
189+
-out test/crl-decode.pem 2>/dev/null
190+
if [ $? -ne 0 ]; then
191+
printf "Failed to generate test/crl-decode.pem\n"
192+
rm -rf "${TMP_DIR}"
193+
exit 1
194+
fi
195+
196+
# Convert PEM CRL to DER
197+
openssl crl -in test/crl-decode.pem -outform DER \
198+
-out test/crl-decode.der 2>/dev/null
199+
if [ $? -ne 0 ]; then
200+
printf "Failed to generate test/crl-decode.der\n"
201+
rm -rf "${TMP_DIR}"
202+
exit 1
203+
fi
204+
rm -rf "${TMP_DIR}"
205+
printf "Generated test/crl-decode.pem and test/crl-decode.der\n"
206+
151207
# Generate SAN test certificates for WolfSSLAltName testing
152208
printf "\nGenerating SAN test certificates...\n"
153209
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"

native/com_wolfssl_WolfSSL.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,19 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_CrlGenerationEnabled
10951095
#endif
10961096
}
10971097

1098+
JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_CrlDecodeEnabled
1099+
(JNIEnv* jenv, jclass jcl)
1100+
{
1101+
(void)jenv;
1102+
(void)jcl;
1103+
1104+
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
1105+
return JNI_TRUE;
1106+
#else
1107+
return JNI_FALSE;
1108+
#endif
1109+
}
1110+
10981111
JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_certReqEnabled
10991112
(JNIEnv* jenv, jclass jcl)
11001113
{

native/com_wolfssl_WolfSSL.h

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

native/com_wolfssl_WolfSSLCRL.c

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,3 +847,228 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1get_1signatu
847847
return NULL;
848848
#endif
849849
}
850+
851+
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1load_1buffer
852+
(JNIEnv* jenv, jclass jcl, jbyteArray buf, jint format)
853+
{
854+
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
855+
WOLFSSL_X509_CRL* crl = NULL;
856+
byte* bufPtr = NULL;
857+
int bufSz = 0;
858+
(void)jcl;
859+
860+
if (jenv == NULL || buf == NULL) {
861+
return 0;
862+
}
863+
864+
bufPtr = (byte*)(*jenv)->GetByteArrayElements(jenv, buf, NULL);
865+
bufSz = (*jenv)->GetArrayLength(jenv, buf);
866+
867+
if (bufPtr == NULL || bufSz <= 0) {
868+
if (bufPtr != NULL) {
869+
(*jenv)->ReleaseByteArrayElements(
870+
jenv, buf, (jbyte*)bufPtr, JNI_ABORT);
871+
}
872+
return 0;
873+
}
874+
875+
if ((int)format == WOLFSSL_FILETYPE_PEM) {
876+
/* PEM format: use BIO to decode */
877+
WOLFSSL_BIO* bio = wolfSSL_BIO_new_mem_buf(bufPtr, bufSz);
878+
if (bio != NULL) {
879+
crl = wolfSSL_PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL);
880+
wolfSSL_BIO_free(bio);
881+
}
882+
}
883+
else {
884+
/* DER format: decode directly */
885+
crl = wolfSSL_d2i_X509_CRL(NULL, (const unsigned char*)bufPtr, bufSz);
886+
}
887+
888+
(*jenv)->ReleaseByteArrayElements(jenv, buf, (jbyte*)bufPtr, JNI_ABORT);
889+
890+
return (jlong)(uintptr_t)crl;
891+
#else
892+
(void)jenv;
893+
(void)jcl;
894+
(void)buf;
895+
(void)format;
896+
return 0;
897+
#endif
898+
}
899+
900+
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1load_1file
901+
(JNIEnv* jenv, jclass jcl, jstring path, jint format)
902+
{
903+
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && \
904+
!defined(NO_FILESYSTEM)
905+
WOLFSSL_X509_CRL* crl = NULL;
906+
const char* cPath = NULL;
907+
XFILE fp = XBADFILE;
908+
(void)jcl;
909+
910+
if (jenv == NULL || path == NULL) {
911+
return 0;
912+
}
913+
914+
cPath = (*jenv)->GetStringUTFChars(jenv, path, NULL);
915+
if (cPath == NULL) {
916+
return 0;
917+
}
918+
919+
fp = XFOPEN(cPath, "rb");
920+
if (fp == XBADFILE) {
921+
(*jenv)->ReleaseStringUTFChars(jenv, path, cPath);
922+
return 0;
923+
}
924+
925+
if ((int)format == WOLFSSL_FILETYPE_PEM) {
926+
crl = wolfSSL_PEM_read_X509_CRL(fp, NULL, NULL, NULL);
927+
}
928+
else {
929+
crl = wolfSSL_d2i_X509_CRL_fp(fp, NULL);
930+
}
931+
932+
XFCLOSE(fp);
933+
(*jenv)->ReleaseStringUTFChars(jenv, path, cPath);
934+
935+
return (jlong)(uintptr_t)crl;
936+
#else
937+
(void)jenv;
938+
(void)jcl;
939+
(void)path;
940+
(void)format;
941+
return 0;
942+
#endif
943+
}
944+
945+
JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1get_1issuer_1name_1string
946+
(JNIEnv* jenv, jclass jcl, jlong crlPtr)
947+
{
948+
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
949+
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
950+
WOLFSSL_X509_NAME* name = NULL;
951+
char* nameStr = NULL;
952+
jstring ret = NULL;
953+
(void)jcl;
954+
955+
if (jenv == NULL || crl == NULL) {
956+
return NULL;
957+
}
958+
959+
name = wolfSSL_X509_CRL_get_issuer_name(crl);
960+
if (name != NULL) {
961+
nameStr = wolfSSL_X509_NAME_oneline(name, NULL, 0);
962+
if (nameStr == NULL) {
963+
return NULL;
964+
}
965+
ret = (*jenv)->NewStringUTF(jenv, nameStr);
966+
XFREE(nameStr, NULL, DYNAMIC_TYPE_OPENSSL);
967+
return ret;
968+
}
969+
return NULL;
970+
#else
971+
(void)jenv;
972+
(void)jcl;
973+
(void)crlPtr;
974+
return NULL;
975+
#endif
976+
}
977+
978+
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1get_1signature_1type
979+
(JNIEnv* jenv, jclass jcl, jlong crlPtr)
980+
{
981+
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
982+
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
983+
(void)jcl;
984+
985+
if (jenv == NULL || crl == NULL) {
986+
return 0;
987+
}
988+
989+
return (jint)wolfSSL_X509_CRL_get_signature_type(crl);
990+
#else
991+
(void)jenv;
992+
(void)jcl;
993+
(void)crlPtr;
994+
return 0;
995+
#endif
996+
}
997+
998+
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1get_1signature_1nid
999+
(JNIEnv* jenv, jclass jcl, jlong crlPtr)
1000+
{
1001+
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
1002+
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
1003+
(void)jcl;
1004+
1005+
if (jenv == NULL || crl == NULL) {
1006+
return 0;
1007+
}
1008+
1009+
return (jint)wolfSSL_X509_CRL_get_signature_nid(crl);
1010+
#else
1011+
(void)jenv;
1012+
(void)jcl;
1013+
(void)crlPtr;
1014+
return 0;
1015+
#endif
1016+
}
1017+
1018+
/* TODO: wolfSSL_X509_CRL_verify() is currently a stub in wolfSSL
1019+
* (src/x509.c, guarded by NO_WOLFSSL_STUB) and always returns 0.
1020+
* This JNI wrapper is provided for API completeness and will work
1021+
* correctly once the native implementation is completed. */
1022+
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1verify
1023+
(JNIEnv* jenv, jclass jcl, jlong crlPtr, jbyteArray pubKey)
1024+
{
1025+
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
1026+
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
1027+
WOLFSSL_EVP_PKEY* pkey = NULL;
1028+
unsigned char* buf = NULL;
1029+
#if LIBWOLFSSL_VERSION_HEX >= 0x04004000
1030+
const unsigned char* ptr = NULL;
1031+
#else
1032+
unsigned char* ptr = NULL;
1033+
#endif
1034+
int pubKeySz;
1035+
int ret;
1036+
(void)jcl;
1037+
1038+
if (jenv == NULL || crl == NULL || pubKey == NULL) {
1039+
return BAD_FUNC_ARG;
1040+
}
1041+
1042+
pubKeySz = (*jenv)->GetArrayLength(jenv, pubKey);
1043+
if (pubKeySz <= 0) {
1044+
return BAD_FUNC_ARG;
1045+
}
1046+
1047+
buf = (unsigned char*)(*jenv)->GetByteArrayElements(jenv, pubKey, NULL);
1048+
if (buf == NULL) {
1049+
return MEMORY_E;
1050+
}
1051+
ptr = buf;
1052+
1053+
/* Note thatwolfSSL_d2i_PUBKEY advances ptr */
1054+
pkey = wolfSSL_d2i_PUBKEY(NULL, &ptr, pubKeySz);
1055+
1056+
(*jenv)->ReleaseByteArrayElements(jenv, pubKey, (jbyte*)buf, JNI_ABORT);
1057+
1058+
if (pkey == NULL) {
1059+
return WOLFSSL_FAILURE;
1060+
}
1061+
1062+
ret = wolfSSL_X509_CRL_verify(crl, pkey);
1063+
1064+
wolfSSL_EVP_PKEY_free(pkey);
1065+
1066+
return ret;
1067+
#else
1068+
(void)jenv;
1069+
(void)jcl;
1070+
(void)crlPtr;
1071+
(void)pubKey;
1072+
return 0;
1073+
#endif
1074+
}

native/com_wolfssl_WolfSSLCRL.h

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)