Merge pull request #341 from cconlon/pathLenFix
Add pathLen support to`WolfSSLCertificate`/`WolfSSLCertRequest` `addExtension()`pull/348/head
commit
b635b5baab
|
|
@ -659,7 +659,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1add_1ext_1via_1
|
|||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1add_1ext_1via_1set_1object_1boolean
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr, jint nid, jboolean extValue, jboolean isCritical)
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr, jint nid, jboolean extValue, jboolean isCritical, jint pathLen)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509ReqPtr;
|
||||
|
|
@ -672,6 +672,17 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1add_1ext_1via_1
|
|||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
/* pathLen >= 0 requires wolfSSL > 5.8.4 which includes fixes so
|
||||
* wolfSSL_ASN1_OBJECT_dup() copies pathlen and wolfSSL_X509_add_ext()
|
||||
* correctly sets pathLengthSet for DER encoding. Without these fixes,
|
||||
* pathLen is silently dropped during cert generation. */
|
||||
if (pathLen >= 0) {
|
||||
#if !((LIBWOLFSSL_VERSION_HEX > 0x05008004) || \
|
||||
defined(WOLFSSL_PR9940_PATCH_APPLIED))
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
ext = wolfSSL_X509_EXTENSION_new();
|
||||
if (ext == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
|
|
@ -699,6 +710,16 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1add_1ext_1via_1
|
|||
}
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS && pathLen >= 0) {
|
||||
obj->pathlen = wolfSSL_ASN1_INTEGER_new();
|
||||
if (obj->pathlen == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
obj->pathlen->length = pathLen;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_X509_EXTENSION_set_object(ext, obj);
|
||||
}
|
||||
|
|
@ -707,7 +728,6 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1add_1ext_1via_1
|
|||
ret = wolfSSL_X509_add_ext(x509, ext, -1);
|
||||
}
|
||||
|
||||
|
||||
if (obj != NULL) {
|
||||
wolfSSL_ASN1_OBJECT_free(obj);
|
||||
}
|
||||
|
|
@ -723,6 +743,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1add_1ext_1via_1
|
|||
(void)nid;
|
||||
(void)extValue;
|
||||
(void)isCritical;
|
||||
(void)pathLen;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,10 +104,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1add_1ext_1via_1
|
|||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_add_ext_via_set_object_boolean
|
||||
* Signature: (JIZZ)I
|
||||
* Signature: (JIZZI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1add_1ext_1via_1set_1object_1boolean
|
||||
(JNIEnv *, jclass, jlong, jint, jboolean, jboolean);
|
||||
(JNIEnv *, jclass, jlong, jint, jboolean, jboolean, jint);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1ext_1via_1
|
|||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1ext_1via_1set_1object_1boolean
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509Ptr, jint nid, jboolean extValue, jboolean isCritical)
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509Ptr, jint nid, jboolean extValue, jboolean isCritical, jint pathLen)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
|
||||
|
|
@ -378,6 +378,17 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1ext_1via_1
|
|||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
/* pathLen >= 0 requires wolfSSL > 5.8.4 which includes fixes so
|
||||
* wolfSSL_ASN1_OBJECT_dup() copies pathlen and wolfSSL_X509_add_ext()
|
||||
* correctly sets pathLengthSet for DER encoding. Without these fixes,
|
||||
* pathLen is silently dropped during cert generation. */
|
||||
if (pathLen >= 0) {
|
||||
#if !((LIBWOLFSSL_VERSION_HEX > 0x05008004) || \
|
||||
defined(WOLFSSL_PR9940_PATCH_APPLIED))
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
ext = wolfSSL_X509_EXTENSION_new();
|
||||
if (ext == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
|
|
@ -405,6 +416,16 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1ext_1via_1
|
|||
}
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS && pathLen >= 0) {
|
||||
obj->pathlen = wolfSSL_ASN1_INTEGER_new();
|
||||
if (obj->pathlen == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
obj->pathlen->length = pathLen;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_X509_EXTENSION_set_object(ext, obj);
|
||||
}
|
||||
|
|
@ -413,7 +434,6 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1ext_1via_1
|
|||
ret = wolfSSL_X509_add_ext(x509, ext, -1);
|
||||
}
|
||||
|
||||
|
||||
if (obj != NULL) {
|
||||
wolfSSL_ASN1_OBJECT_free(obj);
|
||||
}
|
||||
|
|
@ -429,6 +449,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1ext_1via_1
|
|||
(void)nid;
|
||||
(void)extValue;
|
||||
(void)isCritical;
|
||||
(void)pathLen;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -352,10 +352,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1ext_1via_1
|
|||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertificate
|
||||
* Method: X509_add_ext_via_set_object_boolean
|
||||
* Signature: (JIZZ)I
|
||||
* Signature: (JIZZI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1ext_1via_1set_1object_1boolean
|
||||
(JNIEnv *, jclass, jlong, jint, jboolean, jboolean);
|
||||
(JNIEnv *, jclass, jlong, jint, jboolean, jboolean, jint);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertificate
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public class WolfSSLCertRequest {
|
|||
static native int X509_add_ext_via_nconf_nid(long x509Ptr, int nid,
|
||||
String extValue, boolean isCritical);
|
||||
static native int X509_add_ext_via_set_object_boolean(long x509Ptr,
|
||||
int nid, boolean extValue, boolean isCritical);
|
||||
int nid, boolean extValue, boolean isCritical, int pathLen);
|
||||
|
||||
/**
|
||||
* Create new empty WolfSSLCertRequest object, for use with CSR generation
|
||||
|
|
@ -506,6 +506,36 @@ public class WolfSSLCertRequest {
|
|||
public void addExtension(int nid, boolean value, boolean isCritical)
|
||||
throws IllegalStateException, WolfSSLException {
|
||||
|
||||
addExtension(nid, value, -1, isCritical);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Basic Constraints extension with CA flag and path length constraint
|
||||
* to a WolfSSLCertRequest.
|
||||
*
|
||||
* This method allows setting the Basic Constraints extension with both the
|
||||
* CA boolean and an optional path length constraint. The path length limits
|
||||
* the number of intermediate CA certificates that may follow this
|
||||
* certificate in a valid certification path.
|
||||
*
|
||||
* To set Basic Constraints without a path length constraint, use
|
||||
* {@link #addExtension(int, boolean, boolean)} with
|
||||
* {@code WolfSSL.NID_basic_constraints} instead.
|
||||
*
|
||||
* @param nid NID of extension to add. Must be:
|
||||
* WolfSSL.NID_basic_constraints
|
||||
* @param value Boolean value of CA flag (true for CA, false for end entity)
|
||||
* @param pathLen Maximum number of intermediate CA certificates allowed
|
||||
* below this CA. Must be >= 0, or -1 to not set a path length
|
||||
* constraint. Only meaningful when value is true.
|
||||
* @param isCritical Boolean flag indicating if this extension is critical
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed
|
||||
* @throws WolfSSLException if invalid arguments or on native JNI error
|
||||
*/
|
||||
public void addExtension(int nid, boolean value, int pathLen,
|
||||
boolean isCritical) throws IllegalStateException, WolfSSLException {
|
||||
|
||||
int ret = 0;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
|
@ -514,7 +544,7 @@ public class WolfSSLCertRequest {
|
|||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.x509ReqPtr,
|
||||
() -> "entered addExtension(nid: " + nid + ", value: " + value +
|
||||
", isCritical: " + isCritical + ")");
|
||||
", pathLen: " + pathLen + ", isCritical: " + isCritical + ")");
|
||||
}
|
||||
|
||||
if (nid != WolfSSL.NID_basic_constraints) {
|
||||
|
|
@ -522,12 +552,29 @@ public class WolfSSLCertRequest {
|
|||
"Unsupported X509v3 extension NID: " + nid);
|
||||
}
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
ret = X509_add_ext_via_set_object_boolean(
|
||||
this.x509ReqPtr, nid, value, isCritical);
|
||||
if (pathLen < -1) {
|
||||
throw new WolfSSLException(
|
||||
"Path length must be >= 0 or -1, got: " + pathLen);
|
||||
}
|
||||
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
if (!value && pathLen >= 0) {
|
||||
throw new WolfSSLException(
|
||||
"pathLen must not be set when isCA is FALSE (RFC 5280), " +
|
||||
"got pathLen: " + pathLen);
|
||||
}
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
ret = X509_add_ext_via_set_object_boolean(this.x509ReqPtr, nid,
|
||||
value, isCritical, pathLen);
|
||||
}
|
||||
|
||||
if (ret == WolfSSL.NOT_COMPILED_IN) {
|
||||
throw new WolfSSLException(
|
||||
"addExtension NOT_COMPILED_IN, pathLen " +
|
||||
"support requires wolfSSL > 5.8.4 or " +
|
||||
"PR 9940 patch (ret: " + ret + ")");
|
||||
}
|
||||
else if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new WolfSSLException(
|
||||
"Error setting extension into native WOLFSSL_X509 " +
|
||||
"(ret: " + ret + ")");
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ public class WolfSSLCertificate implements Serializable {
|
|||
static native int X509_add_ext_via_nconf_nid(long x509Ptr, int nid,
|
||||
String extValue, boolean isCritical);
|
||||
static native int X509_add_ext_via_set_object_boolean(long x509Ptr,
|
||||
int nid, boolean extValue, boolean isCritical);
|
||||
int nid, boolean extValue, boolean isCritical, int pathLen);
|
||||
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);
|
||||
|
|
@ -1195,6 +1195,36 @@ public class WolfSSLCertificate implements Serializable {
|
|||
public void addExtension(int nid, boolean value, boolean isCritical)
|
||||
throws IllegalStateException, WolfSSLException {
|
||||
|
||||
addExtension(nid, value, -1, isCritical);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Basic Constraints extension with CA flag and path length
|
||||
* constraint to a WOLFSSL_X509.
|
||||
*
|
||||
* This method allows setting the Basic Constraints extension with both the
|
||||
* CA boolean and an optional path length constraint. The path length limits
|
||||
* the number of intermediate CA certificates that may follow this
|
||||
* certificate in a valid certification path.
|
||||
*
|
||||
* To set Basic Constraints without a path length constraint, use
|
||||
* {@link #addExtension(int, boolean, boolean)} with
|
||||
* {@code WolfSSL.NID_basic_constraints} instead.
|
||||
*
|
||||
* @param nid NID of extension to add. Must be:
|
||||
* WolfSSL.NID_basic_constraints
|
||||
* @param value Boolean value of CA flag (true for CA, false for end entity)
|
||||
* @param pathLen Maximum number of intermediate CA certificates allowed
|
||||
* below this CA. Must be >= 0, or -1 to not set a path length
|
||||
* constraint. Only meaningful when value is true.
|
||||
* @param isCritical Boolean flag indicating if this extension is critical
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertificate has been freed
|
||||
* @throws WolfSSLException if invalid arguments or on native JNI error.
|
||||
*/
|
||||
public void addExtension(int nid, boolean value, int pathLen,
|
||||
boolean isCritical) throws IllegalStateException, WolfSSLException {
|
||||
|
||||
int ret = 0;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
|
@ -1203,7 +1233,8 @@ public class WolfSSLCertificate implements Serializable {
|
|||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.x509Ptr,
|
||||
() -> "entering addExtension(nid: " + nid + ", value: " +
|
||||
value + ", isCritical: " + isCritical + ")");
|
||||
value + ", pathLen: " + pathLen + ", isCritical: " +
|
||||
isCritical + ")");
|
||||
}
|
||||
|
||||
if (nid != WolfSSL.NID_basic_constraints) {
|
||||
|
|
@ -1211,12 +1242,29 @@ public class WolfSSLCertificate implements Serializable {
|
|||
"Unsupported X509v3 extension NID: " + nid);
|
||||
}
|
||||
|
||||
synchronized (x509Lock) {
|
||||
ret = X509_add_ext_via_set_object_boolean(
|
||||
this.x509Ptr, nid, value, isCritical);
|
||||
if (pathLen < -1) {
|
||||
throw new WolfSSLException(
|
||||
"Path length must be >= 0 or -1, got: " + pathLen);
|
||||
}
|
||||
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
if (!value && pathLen >= 0) {
|
||||
throw new WolfSSLException(
|
||||
"pathLen must not be set when isCA is FALSE (RFC 5280), " +
|
||||
"got pathLen: " + pathLen);
|
||||
}
|
||||
|
||||
synchronized (x509Lock) {
|
||||
ret = X509_add_ext_via_set_object_boolean(this.x509Ptr, nid, value,
|
||||
isCritical, pathLen);
|
||||
}
|
||||
|
||||
if (ret == WolfSSL.NOT_COMPILED_IN) {
|
||||
throw new WolfSSLException(
|
||||
"addExtension NOT_COMPILED_IN, pathLen " +
|
||||
"support requires wolfSSL > 5.8.4 or " +
|
||||
"PR 9940 patch (ret: " + ret + ")");
|
||||
}
|
||||
else if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new WolfSSLException(
|
||||
"Error setting extension into native WOLFSSL_X509 " +
|
||||
"(ret: " + ret + ")");
|
||||
|
|
|
|||
|
|
@ -74,6 +74,16 @@ public class WolfSSLCertRequestTest {
|
|||
cliEccKeyPem = WolfSSLTestCommon.getPath(cliEccKeyPem);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
/* Internal helper method, generate test SubjectName for cert generation */
|
||||
private WolfSSLX509Name GenerateTestSubjectName() throws WolfSSLException {
|
||||
|
||||
|
|
@ -185,6 +195,51 @@ public class WolfSSLCertRequestTest {
|
|||
req.addExtension(WolfSSL.NID_basic_constraints, true, true);
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, false, true);
|
||||
|
||||
/* Test boolean extension with pathLen */
|
||||
try {
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, true, 0, true);
|
||||
} catch (WolfSSLException e) {
|
||||
if (!isNotCompiledIn(e)) {
|
||||
throw e;
|
||||
}
|
||||
System.out.println("\t\t\t... skipped");
|
||||
}
|
||||
try {
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, true, 3, true);
|
||||
} catch (WolfSSLException e) {
|
||||
if (!isNotCompiledIn(e)) {
|
||||
throw e;
|
||||
}
|
||||
System.out.println("\t\t\t... skipped");
|
||||
}
|
||||
|
||||
/* Invalid pathLen (< -1) should throw WolfSSLException */
|
||||
try {
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, true, -2, true);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("Invalid pathLen did not throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* pathLen with isCA=false should throw (RFC 5280) */
|
||||
try {
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, false, 0, true);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("pathLen with isCA=false did not throw");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Unsupported NID with pathLen should throw exception */
|
||||
try {
|
||||
req.addExtension(123456, true, 0, true);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("Unsupported NID did not throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Adding unsupported NID should throw exception */
|
||||
try {
|
||||
req.addExtension(123456, true, false);
|
||||
|
|
|
|||
|
|
@ -897,6 +897,7 @@ public class WolfSSLCertificateTest {
|
|||
testCertGen_CASigned_UsingFiles();
|
||||
testCertGen_CASigned_UsingBuffers();
|
||||
testCertGen_CASigned_UsingJavaClasses();
|
||||
testCertGen_SelfSigned_WithPathLen();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -960,6 +961,48 @@ public class WolfSSLCertificateTest {
|
|||
() -> x509.setAuthorityKeyIdEx(issuer),
|
||||
"setAuthorityKeyIdEx");
|
||||
|
||||
/* Basic Constraints with pathLen */
|
||||
try {
|
||||
x509.addExtension(WolfSSL.NID_basic_constraints, true, 0, true);
|
||||
} catch (WolfSSLException e) {
|
||||
if (!isNotCompiledIn(e)) {
|
||||
throw e;
|
||||
}
|
||||
System.out.println("\t\t... skipped");
|
||||
}
|
||||
try {
|
||||
x509.addExtension(WolfSSL.NID_basic_constraints, true, 3, true);
|
||||
} catch (WolfSSLException e) {
|
||||
if (!isNotCompiledIn(e)) {
|
||||
throw e;
|
||||
}
|
||||
System.out.println("\t\t... skipped");
|
||||
}
|
||||
|
||||
/* Invalid pathLen (< -1) should throw WolfSSLException */
|
||||
try {
|
||||
x509.addExtension(WolfSSL.NID_basic_constraints, true, -2, true);
|
||||
fail("Expected WolfSSLException for invalid pathLen");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* pathLen with isCA=false should throw (RFC 5280) */
|
||||
try {
|
||||
x509.addExtension(WolfSSL.NID_basic_constraints, false, 0, true);
|
||||
fail("Expected WolfSSLException for pathLen with isCA=false");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Unsupported NID with pathLen overload should throw */
|
||||
try {
|
||||
x509.addExtension(123456, true, 0, true);
|
||||
fail("Expected WolfSSLException for unsupported NID");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
runOrAllowNotCompiled(
|
||||
() -> x509.addCrlDistPoint("http://crl.example.com/ca.crl", false),
|
||||
"addCrlDistPoint");
|
||||
|
|
@ -1571,6 +1614,87 @@ public class WolfSSLCertificateTest {
|
|||
System.out.println("\t... passed");
|
||||
}
|
||||
|
||||
/* Test self-signed CA certificate generation with Basic Constraints
|
||||
* pathLen set, verifying it round-trips through DER encoding.
|
||||
* Requires wolfSSL > 5.8.4 or WOLFSSL_PR9940_PATCH_APPLIED. */
|
||||
private void testCertGen_SelfSigned_WithPathLen()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
|
||||
System.out.print("\tSelf-signed CA (pathLen)");
|
||||
|
||||
WolfSSLCertificate x509 = new WolfSSLCertificate();
|
||||
assertNotNull(x509);
|
||||
|
||||
/* Set notBefore/notAfter dates */
|
||||
Instant now = Instant.now();
|
||||
final Date notBefore = Date.from(now);
|
||||
final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
|
||||
x509.setNotBefore(notBefore);
|
||||
x509.setNotAfter(notAfter);
|
||||
|
||||
/* Set serial number */
|
||||
x509.setSerialNumber(BigInteger.valueOf(99999));
|
||||
|
||||
/* Set Subject Name */
|
||||
WolfSSLX509Name subjectName = GenerateTestSubjectName();
|
||||
assertNotNull(subjectName);
|
||||
x509.setSubjectName(subjectName);
|
||||
|
||||
/* Set Public Key from generated java.security.PublicKey */
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
|
||||
kpg.initialize(2048);
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
x509.setPublicKey(keyPair.getPublic());
|
||||
|
||||
/* Set Extensions */
|
||||
if (WolfSSL.getLibVersionHex() > 0x05006003) {
|
||||
x509.addExtension(WolfSSL.NID_key_usage,
|
||||
"digitalSignature,cRLSign,keyCertSign", true);
|
||||
x509.addExtension(WolfSSL.NID_ext_key_usage,
|
||||
"clientAuth,serverAuth,OCSPSigning", false);
|
||||
}
|
||||
|
||||
/* Basic Constraints: CA=true, pathLen=0. Skip test if
|
||||
* pathLen support not compiled in (older wolfSSL). */
|
||||
try {
|
||||
x509.addExtension(WolfSSL.NID_basic_constraints, true, 0, true);
|
||||
} catch (WolfSSLException e) {
|
||||
if (isNotCompiledIn(e)) {
|
||||
System.out.println("\t... skipped");
|
||||
subjectName.free();
|
||||
x509.free();
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
/* Sign cert, self-signed */
|
||||
x509.signCert(keyPair.getPrivate(), "SHA256");
|
||||
|
||||
/* Output to DER */
|
||||
byte[] derCert = x509.getDer();
|
||||
assertNotNull(derCert);
|
||||
assertTrue(derCert.length > 0);
|
||||
|
||||
/* Re-load generated cert and verify pathLen */
|
||||
WolfSSLCertificate reloaded = new WolfSSLCertificate(derCert,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
assertNotNull(reloaded);
|
||||
assertEquals(1, reloaded.isCA());
|
||||
assertEquals(0, reloaded.getPathLen());
|
||||
|
||||
/* Sanity check generated cert buffers */
|
||||
sanityCheckCertFileBytes(derCert, WolfSSL.SSL_FILETYPE_ASN1);
|
||||
|
||||
/* Free native memory */
|
||||
reloaded.free();
|
||||
subjectName.free();
|
||||
x509.free();
|
||||
|
||||
System.out.println("\t... passed");
|
||||
}
|
||||
|
||||
/* Utility method if needed for testing, print out cert array to file */
|
||||
private void writeOutCertFile(byte[] cert, String path)
|
||||
throws IOException {
|
||||
|
|
|
|||
Loading…
Reference in New Issue