Merge pull request #317 from padelsbach/crl-generation-cert-updates

Add cert/CRL capabilities: skid, akid, dist point, netscape
pull/332/head
Chris Conlon 2026-02-18 14:40:44 -07:00 committed by GitHub
commit 194db8317f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 890 additions and 4 deletions

View File

@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDbTCCAlWgAwIBAgIUZqjaWzuAIDjJjqQW/x9Lyn5H2McwDQYJKoZIhvcNAQEL
BQAwOjEUMBIGA1UEAwwLVGVzdCBDUkwgRFAxFTATBgNVBAoMDHdvbGZTU0wgVGVz
dDELMAkGA1UEBhMCVVMwHhcNMjYwMjA5MTgxMTQzWhcNMjcwMjA5MTgxMTQzWjA6
MRQwEgYDVQQDDAtUZXN0IENSTCBEUDEVMBMGA1UECgwMd29sZlNTTCBUZXN0MQsw
CQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALP/1lo5
T10/LJAck3ImKvrinzS1oubA/YP/w2NTJLzlZQtbvNPW4WhY2LcuUWOSv/VmMSpq
J/mEqEn8P9CfIgtRo0z39+HJJ3aE3ClioH6fTpj284nHZnJdYQFy/9+T4DTLcuiJ
VILqRotqH06JRU4mhR2hqiw7YHI76BlPJAB9pVwGbit6BKWbF5vJRy440AYNCWjs
t/NEhrKnCJugaPqvyhH9ByWI8/wPeyFNXUpuEiZVg+rSYwPr0w4kVBRUVWnDxEam
WKEEPSM1CdY2LJGDT6Qjm6WyVQbWppu1mz6Dg+nvw+h125PyW4Cyim6HAFj3IJcI
6YcDC2lGep7PNmECAwEAAaNrMGkwCQYDVR0TBAIwADALBgNVHQ8EBAMCB4AwMAYD
VR0fBCkwJzAloCOgIYYfaHR0cDovL2NybC5leGFtcGxlLmNvbS90ZXN0LmNybDAd
BgNVHQ4EFgQUXEABbBfseiUjqacQWYMRluxQV+kwDQYJKoZIhvcNAQELBQADggEB
AF21pa2SQXeqmDtYLvhwNWpwpt814nRfejAzlLBLpJB8nf1NE89a53U7ELbZMPNj
tQC/ADNoNGFQmSaPNytXtHNslPM17kSWN+6/JFhKGcWHXgPPM4E5VOZ94H1BK4fh
PMCfMMh+826Y+RK/nsi4NnlmeJy5/QdRgbDfGY4ZZECssHSIbKPP7pgxH/YzDUd/
HIzf5vXeiUG7PXXJhzA38k1HRhuyxOYnsrLMYw/FsDOl/knhH9dF8f+XFVHuFfQv
GH9cm+btX0gM1EaBi1huQcYYNRp2BSa2qSjIeDRg5Bs4i5BENh7wVtZDheGD0SpE
3jhznnX5L4CwmLzlfQkARuU=
-----END CERTIFICATE-----

View File

@ -98,6 +98,37 @@ if [ $? -ne 0 ]; then
fi
printf "Generated ca-keyPkcs8.der\n"
# Generate CRL Distribution Points test cert
printf "Generating test/crl-dp-cert.pem\n"
mkdir -p test
TMP_DIR="$(mktemp -d)"
cat > "${TMP_DIR}/openssl.cnf" <<EOF
[ req ]
distinguished_name = dn
x509_extensions = v3_req
prompt = no
[ dn ]
CN = Test CRL DP
O = wolfSSL Test
C = US
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature
crlDistributionPoints = URI:http://crl.example.com/test.crl
EOF
openssl req -new -newkey rsa:2048 -nodes -x509 -days 365 \
-keyout "${TMP_DIR}/crl-dp-key.pem" -out test/crl-dp-cert.pem \
-config "${TMP_DIR}/openssl.cnf" >/dev/null 2>&1
if [ $? -ne 0 ]; then
printf "Failed to generate test/crl-dp-cert.pem\n"
rm -rf "${TMP_DIR}"
exit 1
fi
rm -rf "${TMP_DIR}"
# Remove text info from intermediate certs, causes issues on Android (WRONG TAG)
printf "Removing text info from intermediate certs\n"
sed -i.bak -n '/-----BEGIN CERTIFICATE-----/,$p' ca-cert.pem
@ -131,4 +162,3 @@ else
fi
printf "\nFinished successfully\n"

View File

@ -545,6 +545,58 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getNID_1dnQualifier
return NID_dnQualifier;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getNID_1subject_1key_1identifier
(JNIEnv* jenv, jclass jcl)
{
(void)jenv;
(void)jcl;
#ifdef WOLFSSL_CERT_EXT
return NID_subject_key_identifier;
#else
return 0;
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getNID_1authority_1key_1identifier
(JNIEnv* jenv, jclass jcl)
{
(void)jenv;
(void)jcl;
#ifdef WOLFSSL_CERT_EXT
return NID_authority_key_identifier;
#else
return 0;
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getNID_1crl_1distribution_1points
(JNIEnv* jenv, jclass jcl)
{
(void)jenv;
(void)jcl;
#ifdef WOLFSSL_CERT_EXT
return NID_crl_distribution_points;
#else
return 0;
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getNID_1netscape_1cert_1type
(JNIEnv* jenv, jclass jcl)
{
(void)jenv;
(void)jcl;
#ifndef IGNORE_NETSCAPE_CERT_TYPE
return NID_netscape_cert_type;
#else
return 0;
#endif
}
/* functions to return BulkCipherAlgorithm enum values from ./wolfssl/ssl.h */
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getBulkCipherAlgorithmEnumNULL
(JNIEnv* jenv, jclass jcl)

View File

@ -221,6 +221,20 @@ extern "C" {
#define com_wolfssl_WolfSSL_ASN_URI_TYPE 6L
#undef com_wolfssl_WolfSSL_ASN_IP_TYPE
#define com_wolfssl_WolfSSL_ASN_IP_TYPE 7L
#undef com_wolfssl_WolfSSL_NS_CERT_TYPE_SSL_CLIENT
#define com_wolfssl_WolfSSL_NS_CERT_TYPE_SSL_CLIENT 128L
#undef com_wolfssl_WolfSSL_NS_CERT_TYPE_SSL_SERVER
#define com_wolfssl_WolfSSL_NS_CERT_TYPE_SSL_SERVER 64L
#undef com_wolfssl_WolfSSL_NS_CERT_TYPE_EMAIL
#define com_wolfssl_WolfSSL_NS_CERT_TYPE_EMAIL 32L
#undef com_wolfssl_WolfSSL_NS_CERT_TYPE_OBJECT_SIGNING
#define com_wolfssl_WolfSSL_NS_CERT_TYPE_OBJECT_SIGNING 16L
#undef com_wolfssl_WolfSSL_NS_CERT_TYPE_SSL_CA
#define com_wolfssl_WolfSSL_NS_CERT_TYPE_SSL_CA 4L
#undef com_wolfssl_WolfSSL_NS_CERT_TYPE_EMAIL_CA
#define com_wolfssl_WolfSSL_NS_CERT_TYPE_EMAIL_CA 2L
#undef com_wolfssl_WolfSSL_NS_CERT_TYPE_OBJECT_CA
#define com_wolfssl_WolfSSL_NS_CERT_TYPE_OBJECT_CA 1L
#undef com_wolfssl_WolfSSL_WOLFSSL_NAMED_GROUP_INVALID
#define com_wolfssl_WolfSSL_WOLFSSL_NAMED_GROUP_INVALID 0L
#undef com_wolfssl_WolfSSL_WOLFSSL_ECC_SECT163K1
@ -409,6 +423,38 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getNID_1ext_1key_1usage
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getNID_1dnQualifier
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_WolfSSL
* Method: getNID_subject_key_identifier
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getNID_1subject_1key_1identifier
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_WolfSSL
* Method: getNID_authority_key_identifier
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getNID_1authority_1key_1identifier
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_WolfSSL
* Method: getNID_crl_distribution_points
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getNID_1crl_1distribution_1points
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_WolfSSL
* Method: getNID_netscape_cert_type
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getNID_1netscape_1cert_1type
(JNIEnv *, jclass);
/*
* Class: com_wolfssl_WolfSSL
* Method: getBulkCipherAlgorithmEnumNULL

View File

@ -156,7 +156,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1set_1lastUpdate
}
else {
/* Extract length from bytes 32-35 (assuming native byte order) */
timeLen = *((int*)(timeBuf + CTC_DATE_SIZE));
XMEMCPY(&timeLen, timeBuf + CTC_DATE_SIZE, sizeof(timeLen));
if (timeLen <= 0 || timeLen > CTC_DATE_SIZE) {
ret = 0;
}
@ -212,7 +212,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1set_1nextUpdate
}
else {
/* Extract length from bytes 32-35 (assuming native byte order) */
timeLen = *((int*)(timeBuf + CTC_DATE_SIZE));
XMEMCPY(&timeLen, timeBuf + CTC_DATE_SIZE, sizeof(timeLen));
if (timeLen <= 0 || timeLen > CTC_DATE_SIZE) {
ret = 0;
}
@ -254,6 +254,8 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1add_1revoked
int serialSz = 0;
int ret = WOLFSSL_SUCCESS;
(void)jcl;
/* Note: date is not currently used until WOLFSSL_X509_REVOKED adds it. */
(void)revDate;
(void)dateFmt;
@ -284,7 +286,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1add_1revoked
(*jenv)->ReleaseByteArrayElements(jenv, serial, (jbyte*)serialBuf,
JNI_ABORT);
wolfSSL_ASN1_INTEGER_free(serialInt);
if (serialInt != NULL) {
wolfSSL_ASN1_INTEGER_free(serialInt);
}
return ret;
#else

View File

@ -570,6 +570,265 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1serialNumb
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1subject_1key_1id
(JNIEnv* jenv, jclass jcl, jlong x509Ptr, jbyteArray skid)
{
/* Subject/Authority Key ID support added after wolfSSL 5.8.4 in PR 9713.
* Version check must be greater than 5.8.4 or patch from PR 9713 must be
* applied and WOLFSSL_PR9713_PATCH_APPLIED defined when compiling this
* wrapper. */
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_EXT) && \
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
((LIBWOLFSSL_VERSION_HEX > 0x05008004) || \
defined(WOLFSSL_PR9713_PATCH_APPLIED))
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
byte* skidBuf = NULL;
int skidSz = 0;
int ret = WOLFSSL_FAILURE;
(void)jcl;
if (jenv == NULL || x509 == NULL || skid == NULL) {
return ret;
}
skidBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, skid, NULL);
skidSz = (*jenv)->GetArrayLength(jenv, skid);
if (skidBuf != NULL && skidSz > 0) {
ret = wolfSSL_X509_set_subject_key_id(x509, skidBuf, skidSz);
}
(*jenv)->ReleaseByteArrayElements(jenv, skid, (jbyte*)skidBuf, JNI_ABORT);
return (jint)ret;
#else
(void)jenv;
(void)jcl;
(void)x509Ptr;
(void)skid;
return (jint)NOT_COMPILED_IN;
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1subject_1key_1id_1ex
(JNIEnv* jenv, jclass jcl, jlong x509Ptr)
{
/* Subject/Authority Key ID support added after wolfSSL 5.8.4 in PR 9713.
* Version check must be greater than 5.8.4 or patch from PR 9713 must be
* applied and WOLFSSL_PR9713_PATCH_APPLIED defined when compiling this
* wrapper. */
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_EXT) && !defined(NO_SHA) && \
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
((LIBWOLFSSL_VERSION_HEX > 0x05008004) || \
defined(WOLFSSL_PR9713_PATCH_APPLIED))
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
int ret = WOLFSSL_FAILURE;
(void)jcl;
if (jenv == NULL || x509 == NULL) {
return ret;
}
ret = wolfSSL_X509_set_subject_key_id_ex(x509);
return (jint)ret;
#else
(void)jenv;
(void)jcl;
(void)x509Ptr;
return (jint)NOT_COMPILED_IN;
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1authority_1key_1id
(JNIEnv* jenv, jclass jcl, jlong x509Ptr, jbyteArray akid)
{
/* Subject/Authority Key ID support added after wolfSSL 5.8.4 in PR 9713.
* Version check must be greater than 5.8.4 or patch from PR 9713 must be
* applied and WOLFSSL_PR9713_PATCH_APPLIED defined when compiling this
* wrapper. */
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_EXT) && \
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
((LIBWOLFSSL_VERSION_HEX > 0x05008004) || \
defined(WOLFSSL_PR9713_PATCH_APPLIED))
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
byte* akidBuf = NULL;
int akidSz = 0;
int ret = WOLFSSL_FAILURE;
(void)jcl;
if (jenv == NULL || x509 == NULL || akid == NULL) {
return ret;
}
akidBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, akid, NULL);
akidSz = (*jenv)->GetArrayLength(jenv, akid);
if (akidBuf != NULL && akidSz > 0) {
ret = wolfSSL_X509_set_authority_key_id(x509, akidBuf, akidSz);
}
(*jenv)->ReleaseByteArrayElements(jenv, akid, (jbyte*)akidBuf, JNI_ABORT);
return (jint)ret;
#else
(void)jenv;
(void)jcl;
(void)x509Ptr;
(void)akid;
return (jint)NOT_COMPILED_IN;
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1authority_1key_1id_1ex
(JNIEnv* jenv, jclass jcl, jlong x509Ptr, jlong issuerPtr)
{
/* Subject/Authority Key ID support added after wolfSSL 5.8.4 in PR 9713.
* Version check must be greater than 5.8.4 or patch from PR 9713 must be
* applied and WOLFSSL_PR9713_PATCH_APPLIED defined when compiling this
* wrapper. */
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_EXT) && !defined(NO_SHA) && \
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
((LIBWOLFSSL_VERSION_HEX > 0x05008004) || \
defined(WOLFSSL_PR9713_PATCH_APPLIED))
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
WOLFSSL_X509* issuer = (WOLFSSL_X509*)(uintptr_t)issuerPtr;
int ret = WOLFSSL_FAILURE;
(void)jcl;
if (jenv == NULL || x509 == NULL || issuer == NULL) {
return ret;
}
ret = wolfSSL_X509_set_authority_key_id_ex(x509, issuer);
return (jint)ret;
#else
(void)jenv;
(void)jcl;
(void)x509Ptr;
(void)issuerPtr;
return (jint)NOT_COMPILED_IN;
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1CRL_1set_1dist_1points
(JNIEnv* jenv, jclass jcl, jlong x509Ptr, jbyteArray der)
{
/* CRL Distribution Points support added after wolfSSL 5.8.4 in PR 9713.
* Version check must be greater than 5.8.4 or patch from PR 9713 must be
* applied and WOLFSSL_PR9713_PATCH_APPLIED defined when compiling this
* wrapper. */
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_EXT) && \
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
((LIBWOLFSSL_VERSION_HEX > 0x05008004) || \
defined(WOLFSSL_PR9713_PATCH_APPLIED))
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
byte* derBuf = NULL;
int derSz = 0;
int ret = WOLFSSL_FAILURE;
(void)jcl;
if (jenv == NULL || x509 == NULL || der == NULL) {
return ret;
}
derBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, der, NULL);
derSz = (*jenv)->GetArrayLength(jenv, der);
if (derBuf != NULL && derSz > 0) {
ret = wolfSSL_X509_CRL_set_dist_points(x509, derBuf, derSz);
}
(*jenv)->ReleaseByteArrayElements(jenv, der, (jbyte*)derBuf, JNI_ABORT);
return (jint)ret;
#else
(void)jenv;
(void)jcl;
(void)x509Ptr;
(void)der;
return (jint)NOT_COMPILED_IN;
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1CRL_1add_1dist_1point
(JNIEnv* jenv, jclass jcl, jlong x509Ptr, jstring uri, jboolean critical)
{
/* CRL Distribution Points support added after wolfSSL 5.8.4 in PR 9713.
* Version check must be greater than 5.8.4 or patch from PR 9713 must be
* applied and WOLFSSL_PR9713_PATCH_APPLIED defined when compiling this
* wrapper. */
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
defined(WOLFSSL_CERT_EXT) && \
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
((LIBWOLFSSL_VERSION_HEX > 0x05008004) || \
defined(WOLFSSL_PR9713_PATCH_APPLIED))
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
const char* uriStr = NULL;
int ret = WOLFSSL_FAILURE;
(void)jcl;
if (jenv == NULL || x509 == NULL || uri == NULL) {
return ret;
}
uriStr = (*jenv)->GetStringUTFChars(jenv, uri, 0);
if (uriStr != NULL) {
ret = wolfSSL_X509_CRL_add_dist_point(x509, uriStr,
(critical == JNI_TRUE) ? 1 : 0);
}
(*jenv)->ReleaseStringUTFChars(jenv, uri, uriStr);
return (jint)ret;
#else
(void)jenv;
(void)jcl;
(void)x509Ptr;
(void)uri;
(void)critical;
return (jint)NOT_COMPILED_IN;
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1ns_1cert_1type
(JNIEnv* jenv, jclass jcl, jlong x509Ptr, jint nsCertType)
{
/* Netscape Certificate Type support added after wolfSSL 5.8.4 in PR 9713.
* Version check must be greater than 5.8.4 or patch from PR 9713 must be
* applied and WOLFSSL_PR9713_PATCH_APPLIED defined when compiling this
* wrapper. */
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
!defined(IGNORE_NETSCAPE_CERT_TYPE) && \
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
((LIBWOLFSSL_VERSION_HEX > 0x05008004) || \
defined(WOLFSSL_PR9713_PATCH_APPLIED))
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
int ret = WOLFSSL_FAILURE;
(void)jcl;
if (jenv == NULL || x509 == NULL) {
return ret;
}
ret = wolfSSL_X509_set_ns_cert_type(x509, (int)nsCertType);
return (jint)ret;
#else
(void)jenv;
(void)jcl;
(void)x509Ptr;
(void)nsCertType;
return (jint)NOT_COMPILED_IN;
#endif
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1sign
(JNIEnv* jenv, jclass jcl, jlong x509Ptr, jint keyType, jbyteArray fileBytes, jint fileFormat, jstring digestAlg)
{

View File

@ -381,6 +381,62 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1notAfter
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1serialNumber
(JNIEnv *, jclass, jlong, jbyteArray);
/*
* Class: com_wolfssl_WolfSSLCertificate
* Method: X509_set_subject_key_id
* Signature: (J[B)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1subject_1key_1id
(JNIEnv *, jclass, jlong, jbyteArray);
/*
* Class: com_wolfssl_WolfSSLCertificate
* Method: X509_set_subject_key_id_ex
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1subject_1key_1id_1ex
(JNIEnv *, jclass, jlong);
/*
* Class: com_wolfssl_WolfSSLCertificate
* Method: X509_set_authority_key_id
* Signature: (J[B)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1authority_1key_1id
(JNIEnv *, jclass, jlong, jbyteArray);
/*
* Class: com_wolfssl_WolfSSLCertificate
* Method: X509_set_authority_key_id_ex
* Signature: (JJ)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1authority_1key_1id_1ex
(JNIEnv *, jclass, jlong, jlong);
/*
* Class: com_wolfssl_WolfSSLCertificate
* Method: X509_CRL_set_dist_points
* Signature: (J[B)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1CRL_1set_1dist_1points
(JNIEnv *, jclass, jlong, jbyteArray);
/*
* Class: com_wolfssl_WolfSSLCertificate
* Method: X509_CRL_add_dist_point
* Signature: (JLjava/lang/String;Z)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1CRL_1add_1dist_1point
(JNIEnv *, jclass, jlong, jstring, jboolean);
/*
* Class: com_wolfssl_WolfSSLCertificate
* Method: X509_set_ns_cert_type
* Signature: (JI)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1ns_1cert_1type
(JNIEnv *, jclass, jlong, jint);
/*
* Class: com_wolfssl_WolfSSLCertificate
* Method: X509_sign

View File

@ -470,6 +470,30 @@ public class WolfSSL {
public static int NID_ext_key_usage;
/** Domain name qualifier NID */
public static int NID_dnQualifier;
/** Subject Key Identifier NID */
public static int NID_subject_key_identifier;
/** Authority Key Identifier NID */
public static int NID_authority_key_identifier;
/** CRL Distribution Points NID */
public static int NID_crl_distribution_points;
/** Netscape Certificate Type NID */
public static int NID_netscape_cert_type;
/* Netscape Certificate Type bit flags */
/** Netscape Cert Type: SSL Client */
public static final int NS_CERT_TYPE_SSL_CLIENT = 0x80;
/** Netscape Cert Type: SSL Server */
public static final int NS_CERT_TYPE_SSL_SERVER = 0x40;
/** Netscape Cert Type: S/MIME */
public static final int NS_CERT_TYPE_EMAIL = 0x20;
/** Netscape Cert Type: Object Signing */
public static final int NS_CERT_TYPE_OBJECT_SIGNING = 0x10;
/** Netscape Cert Type: SSL CA */
public static final int NS_CERT_TYPE_SSL_CA = 0x04;
/** Netscape Cert Type: S/MIME CA */
public static final int NS_CERT_TYPE_EMAIL_CA = 0x02;
/** Netscape Cert Type: Object Signing CA */
public static final int NS_CERT_TYPE_OBJECT_CA = 0x01;
/* -------------- Named Groups (from enum in ssl.h) ----------------- */
/** Invalid named group */
@ -610,6 +634,10 @@ public class WolfSSL {
NID_basic_constraints = getNID_basic_constraints();
NID_ext_key_usage = getNID_ext_key_usage();
NID_dnQualifier = getNID_dnQualifier();
NID_subject_key_identifier = getNID_subject_key_identifier();
NID_authority_key_identifier = getNID_authority_key_identifier();
NID_crl_distribution_points = getNID_crl_distribution_points();
NID_netscape_cert_type = getNID_netscape_cert_type();
/* initialize cipher enum values */
wolfssl_aes = getBulkCipherAlgorithmEnumAES();
@ -679,6 +707,10 @@ public class WolfSSL {
static native int getNID_basic_constraints();
static native int getNID_ext_key_usage();
static native int getNID_dnQualifier();
static native int getNID_subject_key_identifier();
static native int getNID_authority_key_identifier();
static native int getNID_crl_distribution_points();
static native int getNID_netscape_cert_type();
static native int getBulkCipherAlgorithmEnumNULL();
static native int getBulkCipherAlgorithmEnumRC4();

View File

@ -131,6 +131,15 @@ public class WolfSSLCertificate implements Serializable {
static native int X509_set_notBefore(long x509Ptr, long timeSecs);
static native int X509_set_notAfter(long x509Ptr, long timeSecs);
static native int X509_set_serialNumber(long x509Ptr, byte[] serialBytes);
static native int X509_set_subject_key_id(long x509Ptr, byte[] skid);
static native int X509_set_subject_key_id_ex(long x509Ptr);
static native int X509_set_authority_key_id(long x509Ptr, byte[] akid);
static native int X509_set_authority_key_id_ex(long x509Ptr,
long issuerPtr);
static native int X509_CRL_set_dist_points(long x509Ptr, byte[] der);
static native int X509_CRL_add_dist_point(long x509Ptr, String uri,
boolean critical);
static native int X509_set_ns_cert_type(long x509Ptr, int nsCertType);
static native int X509_sign(long x509Ptr, int evpKeyType, byte[] keyBytes,
int format, String digestAlg);
@ -738,6 +747,247 @@ public class WolfSSLCertificate implements Serializable {
}
}
/**
* Sets the Subject Key Identifier extension for this WolfSSLCertificate,
* used when generating X509v3 certificates.
*
* @param skid Byte array containing Subject Key Identifier.
*
* @throws IllegalStateException if WolfSSLCertificate has been freed.
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
*/
public void setSubjectKeyId(byte[] skid)
throws IllegalStateException, WolfSSLException {
int ret = 0;
confirmObjectIsActive();
if (skid == null || skid.length == 0) {
throw new WolfSSLException("Subject Key Identifier is null/empty");
}
synchronized (x509Lock) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, this.x509Ptr,
() -> "entering setSubjectKeyId(byte[])");
ret = X509_set_subject_key_id(this.x509Ptr, skid);
}
if (ret != WolfSSL.SSL_SUCCESS) {
throw new WolfSSLException(
"Error setting subject key id into native WOLFSSL_X509 " +
"(ret: " + ret + ")");
}
}
/**
* Sets the Subject Key Identifier extension for this WolfSSLCertificate
* using the public key currently set in the certificate.
*
* @throws IllegalStateException if WolfSSLCertificate has been freed.
* @throws WolfSSLException if native JNI error occurs.
*/
public void setSubjectKeyIdEx()
throws IllegalStateException, WolfSSLException {
int ret = 0;
confirmObjectIsActive();
synchronized (x509Lock) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, this.x509Ptr,
() -> "entering setSubjectKeyIdEx()");
ret = X509_set_subject_key_id_ex(this.x509Ptr);
}
if (ret != WolfSSL.SSL_SUCCESS) {
throw new WolfSSLException(
"Error setting subject key id (ex) into native WOLFSSL_X509 " +
"(ret: " + ret + ")");
}
}
/**
* Sets the Authority Key Identifier extension for this WolfSSLCertificate,
* used when generating X509v3 certificates.
*
* @param akid Byte array containing Authority Key Identifier.
*
* @throws IllegalStateException if WolfSSLCertificate has been freed.
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
*/
public void setAuthorityKeyId(byte[] akid)
throws IllegalStateException, WolfSSLException {
int ret = 0;
confirmObjectIsActive();
if (akid == null || akid.length == 0) {
throw new WolfSSLException(
"Authority Key Identifier is null/empty");
}
synchronized (x509Lock) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, this.x509Ptr,
() -> "entering setAuthorityKeyId(byte[])");
ret = X509_set_authority_key_id(this.x509Ptr, akid);
}
if (ret != WolfSSL.SSL_SUCCESS) {
throw new WolfSSLException(
"Error setting authority key id into native WOLFSSL_X509 " +
"(ret: " + ret + ")");
}
}
/**
* Sets the Authority Key Identifier extension for this WolfSSLCertificate
* using the issuer certificate.
*
* @param issuer Issuer certificate used to derive the Authority Key ID.
*
* @throws IllegalStateException if WolfSSLCertificate has been freed.
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
*/
public void setAuthorityKeyIdEx(WolfSSLCertificate issuer)
throws IllegalStateException, WolfSSLException {
int ret = 0;
long issuerX509Ptr;
confirmObjectIsActive();
if (issuer == null) {
throw new WolfSSLException("Issuer certificate is null");
}
issuerX509Ptr = issuer.getX509Ptr();
synchronized (x509Lock) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, this.x509Ptr,
() -> "entering setAuthorityKeyIdEx(issuerPtr=" +
issuerX509Ptr + ")");
ret = X509_set_authority_key_id_ex(this.x509Ptr,
issuerX509Ptr);
}
if (ret != WolfSSL.SSL_SUCCESS) {
throw new WolfSSLException(
"Error setting authority key id (ex) into native " +
"WOLFSSL_X509 (ret: " + ret + ")");
}
}
/**
* Sets the CRL Distribution Points extension from DER data.
*
* @param der DER-encoded CRL Distribution Points extension.
*
* @throws IllegalStateException if WolfSSLCertificate has been freed.
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
*/
public void setCrlDistPoints(byte[] der)
throws IllegalStateException, WolfSSLException {
int ret = 0;
confirmObjectIsActive();
if (der == null || der.length == 0) {
throw new WolfSSLException("CRL dist points DER is null/empty");
}
synchronized (x509Lock) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, this.x509Ptr,
() -> "entering setCrlDistPoints(byte[])");
ret = X509_CRL_set_dist_points(this.x509Ptr, der);
}
if (ret != WolfSSL.SSL_SUCCESS) {
throw new WolfSSLException(
"Error setting CRL dist points into native WOLFSSL_X509 " +
"(ret: " + ret + ")");
}
}
/**
* Adds a CRL Distribution Point URI.
*
* @param uri URI string of the distribution point.
* @param critical Whether to mark the extension critical.
*
* @throws IllegalStateException if WolfSSLCertificate has been freed.
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
*/
public void addCrlDistPoint(String uri, boolean critical)
throws IllegalStateException, WolfSSLException {
int ret = 0;
confirmObjectIsActive();
if (uri == null || uri.isEmpty()) {
throw new WolfSSLException("CRL dist point URI is null/empty");
}
synchronized (x509Lock) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, this.x509Ptr,
() -> "entering addCrlDistPoint(" + uri + ", critical: " +
critical + ")");
ret = X509_CRL_add_dist_point(this.x509Ptr, uri, critical);
}
if (ret != WolfSSL.SSL_SUCCESS) {
throw new WolfSSLException(
"Error adding CRL dist point into native WOLFSSL_X509 " +
"(ret: " + ret + ")");
}
}
/**
* Sets the Netscape Certificate Type extension.
*
* @param nsCertType Netscape cert type bitmask.
*
* @throws IllegalStateException if WolfSSLCertificate has been freed.
* @throws WolfSSLException if native JNI error occurs.
*/
public void setNsCertType(int nsCertType)
throws IllegalStateException, WolfSSLException {
int ret = 0;
confirmObjectIsActive();
synchronized (x509Lock) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, this.x509Ptr,
() -> "entering setNsCertType(" + nsCertType + ")");
ret = X509_set_ns_cert_type(this.x509Ptr, nsCertType);
}
if (ret != WolfSSL.SSL_SUCCESS) {
throw new WolfSSLException(
"Error setting ns cert type into native WOLFSSL_X509 " +
"(ret: " + ret + ")");
}
}
/**
* Sets the notBefore date for this WolfSSLCertificate, used when
* generating X509v3 certificates.
@ -973,6 +1223,28 @@ public class WolfSSLCertificate implements Serializable {
}
}
/**
* Add IP address Subject Alternative Name.
*
* Convenience method for adding an IP address to the Subject Alternative
* Name extension.
*
* @param ipAddress IP address string (e.g., "192.168.1.1" or "::1")
*
* @throws IllegalStateException if WolfSSLCertificate has been freed.
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
*/
public void addAltNameIP(String ipAddress)
throws IllegalStateException, WolfSSLException {
if (ipAddress == null || ipAddress.isEmpty()) {
throw new WolfSSLException(
"IP address must not be null or empty");
}
addAltName(ipAddress, WolfSSL.ASN_IP_TYPE);
}
/**
* Sign certificate with private key from file.
*

View File

@ -78,6 +78,7 @@ public class WolfSSLCertificateTest {
public static String serverCertPem = "examples/certs/server-cert.pem";
public static String external = "examples/certs/ca-google-root.der";
public static String sanTestDir = "examples/certs/san-test";
public static String crlDpCertPem = "examples/certs/test/crl-dp-cert.pem";
public static String sanTestUpnCert = null;
public static String sanTestAllTypesCert = null;
public static String sanTestAllTypesDer = null;
@ -93,6 +94,34 @@ public class WolfSSLCertificateTest {
public static String bogusFile = "/dev/null";
private WolfSSLCertificate cert;
private interface ThrowingRunnable {
void run() throws WolfSSLException, WolfSSLJNIException, IOException;
}
private boolean isNotCompiledIn(WolfSSLException e) {
String msg = e.getMessage();
if (msg == null) {
return false;
}
return msg.contains(Integer.toString(WolfSSL.NOT_COMPILED_IN)) ||
msg.contains("NOT_COMPILED_IN");
}
private void runOrAllowNotCompiled(ThrowingRunnable r, String label)
throws WolfSSLException, WolfSSLJNIException, IOException {
try {
r.run();
} catch (WolfSSLException e) {
if (isNotCompiledIn(e)) {
System.out.println("\t\t" + label +
" ... NOT_COMPILED_IN (skipping)");
return;
}
throw e;
}
}
@BeforeClass
public static void setCertPaths() throws WolfSSLException {
@ -112,6 +141,7 @@ public class WolfSSLCertificateTest {
serverCertPem = WolfSSLTestCommon.getPath(serverCertPem);
external = WolfSSLTestCommon.getPath(external);
sanTestDir = WolfSSLTestCommon.getPath(sanTestDir);
crlDpCertPem = WolfSSLTestCommon.getPath(crlDpCertPem);
sanTestUpnCert = sanTestDir + "/san-test-othername-upn.pem";
sanTestAllTypesCert = sanTestDir + "/san-test-all-types.pem";
sanTestAllTypesDer = sanTestDir + "/san-test-all-types.der";
@ -870,6 +900,90 @@ public class WolfSSLCertificateTest {
}
}
@Test
public void testWolfSSLCertificateExtensionSetters()
throws WolfSSLException, WolfSSLJNIException, IOException,
CertificateException {
System.out.println("WolfSSLCertificate extension setters");
if (WolfSSL.FileSystemEnabled() == false) {
System.out.println("\tfilesystem disabled, skipping");
return;
}
WolfSSLCertificate x509 = new WolfSSLCertificate();
assertNotNull(x509);
WolfSSLX509Name subjectName = GenerateTestSubjectName();
assertNotNull(subjectName);
WolfSSLCertificate issuer =
new WolfSSLCertificate(caCertPem, WolfSSL.SSL_FILETYPE_PEM);
assertNotNull(issuer);
/* Minimal required fields for extensions that depend on */
/* pubkey/issuer */
Instant now = Instant.now();
x509.setNotBefore(Date.from(now));
x509.setNotAfter(Date.from(now.plus(Duration.ofDays(365))));
x509.setSerialNumber(BigInteger.valueOf(67890));
x509.setSubjectName(subjectName);
x509.setIssuerName(issuer);
x509.setPublicKey(cliKeyPubDer, WolfSSL.RSAk,
WolfSSL.SSL_FILETYPE_ASN1);
/* Arbitrary 20-byte test vectors for SKID/AKID content. */
final byte[] skid = new byte[] {
0x01, 0x02, 0x03, 0x04, 0x05,
0x06, 0x07, 0x08, 0x09, 0x0A,
0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14
};
final byte[] akid = new byte[] {
0x10, 0x11, 0x12, 0x13, 0x14,
0x15, 0x16, 0x17, 0x18, 0x19,
0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
0x1F, 0x20, 0x21, 0x22, 0x23
};
runOrAllowNotCompiled(
() -> x509.setSubjectKeyId(skid),
"setSubjectKeyId");
runOrAllowNotCompiled(
() -> x509.setSubjectKeyIdEx(),
"setSubjectKeyIdEx");
runOrAllowNotCompiled(
() -> x509.setAuthorityKeyId(akid),
"setAuthorityKeyId");
runOrAllowNotCompiled(
() -> x509.setAuthorityKeyIdEx(issuer),
"setAuthorityKeyIdEx");
runOrAllowNotCompiled(
() -> x509.addCrlDistPoint("http://crl.example.com/ca.crl", false),
"addCrlDistPoint");
byte[] crlDpDer = issuer.getExtension("2.5.29.31");
if (crlDpDer != null && crlDpDer.length > 0) {
runOrAllowNotCompiled(
() -> x509.setCrlDistPoints(crlDpDer),
"setCrlDistPoints");
} else {
System.out.println("\t\tsetCrlDistPoints ... no DER available");
}
runOrAllowNotCompiled(
() -> x509.setNsCertType(0x80),
"setNsCertType");
subjectName.free();
issuer.free();
x509.free();
System.out.println("\t\t... passed");
}
/* Quick sanity check on certificate bytes. Loads cert into new
* WolfSSLCertificate object, tries to get various elements and
* simply verify if not null / etc. */