Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions native/com_wolfssl_WolfSSLCertificate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1565,6 +1565,107 @@ JNIEXPORT jbooleanArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1k
return ret;
}

/* Helper function to add an Extended Key Usage (EKU) OID string to the
* jobjectArray array if the flag is set. Returns updated index in array. */
static int addEkuOid(JNIEnv* jenv, jobjectArray ret, int idx,
unsigned int ekuBits, unsigned int flag, int nid)
{
WOLFSSL_ASN1_OBJECT* obj = NULL;
jstring ekuStr = NULL;
char oidBuf[128];
int oidLen = 0;

if (ekuBits & flag) {

/* Convert NID to WOLFSSL_ASN1_OBJECT */
obj = wolfSSL_OBJ_nid2obj(nid);
if (obj != NULL) {

/* Convert WOLFSSL_ASN1_OBJECT to OID string */
oidLen = wolfSSL_OBJ_obj2txt(oidBuf, sizeof(oidBuf), obj, 1);
if (oidLen > 0) {

/* Create Java String and add to array */
ekuStr = (*jenv)->NewStringUTF(jenv, oidBuf);
if (ekuStr != NULL) {
(*jenv)->SetObjectArrayElement(jenv, ret, idx, ekuStr);
(*jenv)->DeleteLocalRef(jenv, ekuStr);
idx++;
}
}

/* Free WOLFSSL_ASN1_OBJECT */
wolfSSL_ASN1_OBJECT_free(obj);
}
}

return idx;
}

JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1extended_1key_1usage
(JNIEnv* jenv, jclass jcl, jlong x509Ptr)
{
jobjectArray ret = NULL;
jclass stringClass = NULL;
unsigned int ekuBits = 0;
int ekuCount = 0;
int idx = 0;
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
(void)jcl;

if (jenv == NULL || x509 == NULL) {
return NULL;
}

/* Get extended key usage bitmask from wolfSSL */
ekuBits = wolfSSL_X509_get_extended_key_usage(x509);
if (ekuBits == 0) {
return NULL;
}

/* Count how many EKU bits are set */
if (ekuBits & XKU_SSL_SERVER) ekuCount++;
if (ekuBits & XKU_SSL_CLIENT) ekuCount++;
if (ekuBits & XKU_CODE_SIGN) ekuCount++;
if (ekuBits & XKU_SMIME) ekuCount++;
if (ekuBits & XKU_TIMESTAMP) ekuCount++;
if (ekuBits & XKU_OCSP_SIGN) ekuCount++;

if (ekuCount == 0) {
return NULL;
}

/* Create String[] array to return */
stringClass = (*jenv)->FindClass(jenv, "java/lang/String");
if (stringClass == NULL) {
return NULL;
}

ret = (*jenv)->NewObjectArray(jenv, ekuCount, stringClass, NULL);
if (ret == NULL) {
(*jenv)->DeleteLocalRef(jenv, stringClass);
return NULL;
}

/* Add each EKU OID string to array */
idx = addEkuOid(jenv, ret, idx, ekuBits, XKU_SSL_SERVER,
EKU_SERVER_AUTH_OID);
idx = addEkuOid(jenv, ret, idx, ekuBits, XKU_SSL_CLIENT,
EKU_CLIENT_AUTH_OID);
idx = addEkuOid(jenv, ret, idx, ekuBits, XKU_CODE_SIGN,
EKU_CODESIGNING_OID);
idx = addEkuOid(jenv, ret, idx, ekuBits, XKU_SMIME,
EKU_EMAILPROTECT_OID);
idx = addEkuOid(jenv, ret, idx, ekuBits, XKU_TIMESTAMP,
EKU_TIMESTAMP_OID);
idx = addEkuOid(jenv, ret, idx, ekuBits, XKU_OCSP_SIGN,
EKU_OCSP_SIGN_OID);

(*jenv)->DeleteLocalRef(jenv, stringClass);

return ret;
}

JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1extension
(JNIEnv* jenv, jclass jcl, jlong x509Ptr, jstring oidIn)
{
Expand Down
8 changes: 8 additions & 0 deletions native/com_wolfssl_WolfSSLCertificate.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions native/com_wolfssl_WolfSSLX509StoreCtx.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,17 @@ JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_WolfSSLX509StoreCtx_X509_1STORE_
}
XMEMCPY(buf, der, derSz);
(*jenv)->ReleaseByteArrayElements(jenv, derArr, buf, 0);

#if LIBWOLFSSL_VERSION_HEX >= 0x05008000
/* Reverse order, so peer cert is first in returned array,
* followed by intermediates, lastly by root. Native
* wolfSSL_X509_STORE_GetCerts() returns certs in order of
* root to peer, but Java/JSSE expects peer to root */
(*jenv)->SetObjectArrayElement(jenv, certArr, skNum-1-i, derArr);
#else
/* wolfSSL < 5.8.0 returns certs peer->root, matches Java needs */
(*jenv)->SetObjectArrayElement(jenv, certArr, i, derArr);
#endif
(*jenv)->DeleteLocalRef(jenv, derArr);
}
}
Expand Down
29 changes: 29 additions & 0 deletions src/java/com/wolfssl/WolfSSLCertificate.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public class WolfSSLCertificate implements Serializable {
static native int X509_get_pathLength(long x509);
static native int X509_verify(long x509, byte[] pubKey, int pubKeySz);
static native boolean[] X509_get_key_usage(long x509);
static native String[] X509_get_extended_key_usage(long x509);
static native byte[] X509_get_extension(long x509, String oid);
static native int X509_is_extension_set(long x509, String oid);
static native String X509_get_next_altname(long x509);
Expand Down Expand Up @@ -1550,6 +1551,34 @@ public boolean[] getKeyUsage() throws IllegalStateException {
}
}

/**
* Get extended key usage OIDs from X.509 certificate.
*
* Returns an array of OID strings representing the extended key usage
* values present in the certificate. Common OIDs include:
* - 1.3.6.1.5.5.7.3.1 (TLS Web Server Authentication / serverAuth)
* - 1.3.6.1.5.5.7.3.2 (TLS Web Client Authentication / clientAuth)
* - 1.3.6.1.5.5.7.3.3 (Code Signing / codeSigning)
* - 1.3.6.1.5.5.7.3.4 (Email Protection / emailProtection)
*
* @return Array of OID strings, or null if Extended Key Usage extension
* is not present in certificate
*
* @throws IllegalStateException if WolfSSLCertificate has been freed
*/
public String[] getExtendedKeyUsage() throws IllegalStateException {

confirmObjectIsActive();

synchronized (x509Lock) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, this.x509Ptr,
() -> "entering getExtendedKeyUsage()");

return X509_get_extended_key_usage(this.x509Ptr);
}
}

/**
* Get DER encoded extension value from a specified OID
*
Expand Down
Loading
Loading