Skip to content

Commit 9b067ce

Browse files
authored
Merge pull request #289 from cconlon/wolfsslEngineMemCleanup
SSLEngine memory leak fix, X509ExtendedTrustManager chain sorting fix, support for getExtendedKeyUsage()
2 parents ca4bfe1 + c44f1c8 commit 9b067ce

15 files changed

Lines changed: 1443 additions & 411 deletions

native/com_wolfssl_WolfSSLCertificate.c

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1565,6 +1565,107 @@ JNIEXPORT jbooleanArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1k
15651565
return ret;
15661566
}
15671567

1568+
/* Helper function to add an Extended Key Usage (EKU) OID string to the
1569+
* jobjectArray array if the flag is set. Returns updated index in array. */
1570+
static int addEkuOid(JNIEnv* jenv, jobjectArray ret, int idx,
1571+
unsigned int ekuBits, unsigned int flag, int nid)
1572+
{
1573+
WOLFSSL_ASN1_OBJECT* obj = NULL;
1574+
jstring ekuStr = NULL;
1575+
char oidBuf[128];
1576+
int oidLen = 0;
1577+
1578+
if (ekuBits & flag) {
1579+
1580+
/* Convert NID to WOLFSSL_ASN1_OBJECT */
1581+
obj = wolfSSL_OBJ_nid2obj(nid);
1582+
if (obj != NULL) {
1583+
1584+
/* Convert WOLFSSL_ASN1_OBJECT to OID string */
1585+
oidLen = wolfSSL_OBJ_obj2txt(oidBuf, sizeof(oidBuf), obj, 1);
1586+
if (oidLen > 0) {
1587+
1588+
/* Create Java String and add to array */
1589+
ekuStr = (*jenv)->NewStringUTF(jenv, oidBuf);
1590+
if (ekuStr != NULL) {
1591+
(*jenv)->SetObjectArrayElement(jenv, ret, idx, ekuStr);
1592+
(*jenv)->DeleteLocalRef(jenv, ekuStr);
1593+
idx++;
1594+
}
1595+
}
1596+
1597+
/* Free WOLFSSL_ASN1_OBJECT */
1598+
wolfSSL_ASN1_OBJECT_free(obj);
1599+
}
1600+
}
1601+
1602+
return idx;
1603+
}
1604+
1605+
JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1extended_1key_1usage
1606+
(JNIEnv* jenv, jclass jcl, jlong x509Ptr)
1607+
{
1608+
jobjectArray ret = NULL;
1609+
jclass stringClass = NULL;
1610+
unsigned int ekuBits = 0;
1611+
int ekuCount = 0;
1612+
int idx = 0;
1613+
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
1614+
(void)jcl;
1615+
1616+
if (jenv == NULL || x509 == NULL) {
1617+
return NULL;
1618+
}
1619+
1620+
/* Get extended key usage bitmask from wolfSSL */
1621+
ekuBits = wolfSSL_X509_get_extended_key_usage(x509);
1622+
if (ekuBits == 0) {
1623+
return NULL;
1624+
}
1625+
1626+
/* Count how many EKU bits are set */
1627+
if (ekuBits & XKU_SSL_SERVER) ekuCount++;
1628+
if (ekuBits & XKU_SSL_CLIENT) ekuCount++;
1629+
if (ekuBits & XKU_CODE_SIGN) ekuCount++;
1630+
if (ekuBits & XKU_SMIME) ekuCount++;
1631+
if (ekuBits & XKU_TIMESTAMP) ekuCount++;
1632+
if (ekuBits & XKU_OCSP_SIGN) ekuCount++;
1633+
1634+
if (ekuCount == 0) {
1635+
return NULL;
1636+
}
1637+
1638+
/* Create String[] array to return */
1639+
stringClass = (*jenv)->FindClass(jenv, "java/lang/String");
1640+
if (stringClass == NULL) {
1641+
return NULL;
1642+
}
1643+
1644+
ret = (*jenv)->NewObjectArray(jenv, ekuCount, stringClass, NULL);
1645+
if (ret == NULL) {
1646+
(*jenv)->DeleteLocalRef(jenv, stringClass);
1647+
return NULL;
1648+
}
1649+
1650+
/* Add each EKU OID string to array */
1651+
idx = addEkuOid(jenv, ret, idx, ekuBits, XKU_SSL_SERVER,
1652+
EKU_SERVER_AUTH_OID);
1653+
idx = addEkuOid(jenv, ret, idx, ekuBits, XKU_SSL_CLIENT,
1654+
EKU_CLIENT_AUTH_OID);
1655+
idx = addEkuOid(jenv, ret, idx, ekuBits, XKU_CODE_SIGN,
1656+
EKU_CODESIGNING_OID);
1657+
idx = addEkuOid(jenv, ret, idx, ekuBits, XKU_SMIME,
1658+
EKU_EMAILPROTECT_OID);
1659+
idx = addEkuOid(jenv, ret, idx, ekuBits, XKU_TIMESTAMP,
1660+
EKU_TIMESTAMP_OID);
1661+
idx = addEkuOid(jenv, ret, idx, ekuBits, XKU_OCSP_SIGN,
1662+
EKU_OCSP_SIGN_OID);
1663+
1664+
(*jenv)->DeleteLocalRef(jenv, stringClass);
1665+
1666+
return ret;
1667+
}
1668+
15681669
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1extension
15691670
(JNIEnv* jenv, jclass jcl, jlong x509Ptr, jstring oidIn)
15701671
{

native/com_wolfssl_WolfSSLCertificate.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_WolfSSLX509StoreCtx.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,17 @@ JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_WolfSSLX509StoreCtx_X509_1STORE_
9393
}
9494
XMEMCPY(buf, der, derSz);
9595
(*jenv)->ReleaseByteArrayElements(jenv, derArr, buf, 0);
96+
97+
#if LIBWOLFSSL_VERSION_HEX >= 0x05008000
9698
/* Reverse order, so peer cert is first in returned array,
9799
* followed by intermediates, lastly by root. Native
98100
* wolfSSL_X509_STORE_GetCerts() returns certs in order of
99101
* root to peer, but Java/JSSE expects peer to root */
100102
(*jenv)->SetObjectArrayElement(jenv, certArr, skNum-1-i, derArr);
103+
#else
104+
/* wolfSSL < 5.8.0 returns certs peer->root, matches Java needs */
105+
(*jenv)->SetObjectArrayElement(jenv, certArr, i, derArr);
106+
#endif
101107
(*jenv)->DeleteLocalRef(jenv, derArr);
102108
}
103109
}

src/java/com/wolfssl/WolfSSLCertificate.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ public class WolfSSLCertificate implements Serializable {
9898
static native int X509_get_pathLength(long x509);
9999
static native int X509_verify(long x509, byte[] pubKey, int pubKeySz);
100100
static native boolean[] X509_get_key_usage(long x509);
101+
static native String[] X509_get_extended_key_usage(long x509);
101102
static native byte[] X509_get_extension(long x509, String oid);
102103
static native int X509_is_extension_set(long x509, String oid);
103104
static native String X509_get_next_altname(long x509);
@@ -1550,6 +1551,34 @@ public boolean[] getKeyUsage() throws IllegalStateException {
15501551
}
15511552
}
15521553

1554+
/**
1555+
* Get extended key usage OIDs from X.509 certificate.
1556+
*
1557+
* Returns an array of OID strings representing the extended key usage
1558+
* values present in the certificate. Common OIDs include:
1559+
* - 1.3.6.1.5.5.7.3.1 (TLS Web Server Authentication / serverAuth)
1560+
* - 1.3.6.1.5.5.7.3.2 (TLS Web Client Authentication / clientAuth)
1561+
* - 1.3.6.1.5.5.7.3.3 (Code Signing / codeSigning)
1562+
* - 1.3.6.1.5.5.7.3.4 (Email Protection / emailProtection)
1563+
*
1564+
* @return Array of OID strings, or null if Extended Key Usage extension
1565+
* is not present in certificate
1566+
*
1567+
* @throws IllegalStateException if WolfSSLCertificate has been freed
1568+
*/
1569+
public String[] getExtendedKeyUsage() throws IllegalStateException {
1570+
1571+
confirmObjectIsActive();
1572+
1573+
synchronized (x509Lock) {
1574+
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
1575+
WolfSSLDebug.INFO, this.x509Ptr,
1576+
() -> "entering getExtendedKeyUsage()");
1577+
1578+
return X509_get_extended_key_usage(this.x509Ptr);
1579+
}
1580+
}
1581+
15531582
/**
15541583
* Get DER encoded extension value from a specified OID
15551584
*

0 commit comments

Comments
 (0)