Skip to content
Open
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
26 changes: 23 additions & 3 deletions native/com_wolfssl_WolfSSLSession.c
Original file line number Diff line number Diff line change
Expand Up @@ -2858,9 +2858,29 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_sessionReused
return wolfSSL_session_reused(ssl);
}

JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_getPeerCertificate
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_getPeerCertificateCount
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
{
#ifdef KEEP_PEER_CERT
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
(void)jenv;
(void)jcl;
if (ssl == NULL) {
return (jlong)0;
}
WOLFSSL_X509_CHAIN* chain = wolfSSL_get_peer_chain(ssl);
return wolfSSL_get_chain_count(chain);
#else
(void)jenv;
(void)jcl;
(void)sslPtr;
return 0;
#endif
}

JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_getPeerCertificate
(JNIEnv* jenv, jobject jcl, jlong sslPtr, jint index)
{
#ifdef KEEP_PEER_CERT
WOLFSSL_X509* x509 = NULL;
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
Expand All @@ -2870,8 +2890,8 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_getPeerCertificate
if (ssl == NULL) {
return (jlong)0;
}

x509 = wolfSSL_get_peer_certificate(ssl);
WOLFSSL_X509_CHAIN* chain = wolfSSL_get_peer_chain(ssl);
x509 = wolfSSL_get_chain_X509(chain, index);

return (jlong)(uintptr_t)x509;
#else
Expand Down
12 changes: 10 additions & 2 deletions native/com_wolfssl_WolfSSLSession.h

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

29 changes: 26 additions & 3 deletions src/java/com/wolfssl/WolfSSLSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,8 @@ private native int read(long ssl, ByteBuffer data, int sz, int timeout)
private native long getDtlsReplayDropCount(long ssl);
private native InetSocketAddress dtlsGetPeer(long ssl);
private native int sessionReused(long ssl);
private native long getPeerCertificate(long ssl);
private native int getPeerCertificateCount(long ssl);
private native long getPeerCertificate(long ssl, int index);
private native String getPeerX509Issuer(long ssl, long x509);
private native String getPeerX509Subject(long ssl, long x509);
private native String getPeerX509AltName(long ssl, long x509);
Expand Down Expand Up @@ -2590,6 +2591,27 @@ public int sessionReused()
return ret;
}

/**
* Returns the number of certificates in the peer's certificate chain.
*
* @return number of certificates in the peer's certificate chain.
* @throws IllegalStateException WolfSSLContext has been freed
* @throws WolfSSLJNIException Internal JNI error
* @see WolfSSLSession#getPeerCertificate(int)
*/
public int getPeerCertificateCount()
throws IllegalStateException, WolfSSLJNIException {

confirmObjectIsActive();

synchronized (sslLock) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, this.sslPtr, "entered getPeerCertificateCount()");

return getPeerCertificateCount(this.sslPtr);
}
}

/**
* Gets the native (long) WOLFSSL_X509 pointer to the peer's certificate.
* This can be used to retrieve further information about the peer's
Expand All @@ -2606,6 +2628,7 @@ public int sessionReused()
* Pointer should be freed by calling:
* WolfSSLCertificate.freeX509(long x509);
*
* @param index index of the certificate in the peer's certificate chain
* @return (long) WOLFSSL_X509 pointer to the peer's certificate.
* @throws IllegalStateException WolfSSLContext has been freed
* @throws WolfSSLJNIException Internal JNI error
Expand All @@ -2614,7 +2637,7 @@ public int sessionReused()
* @see WolfSSLSession#getVersion()
* @see WolfSSLSession#getCurrentCipher()
*/
public long getPeerCertificate()
public long getPeerCertificate(int index)
throws IllegalStateException, WolfSSLJNIException {

confirmObjectIsActive();
Expand All @@ -2623,7 +2646,7 @@ public long getPeerCertificate()
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, this.sslPtr, "entered getPeerCertificate()");

return getPeerCertificate(this.sslPtr);
return getPeerCertificate(this.sslPtr, index);
}
}

Expand Down
157 changes: 95 additions & 62 deletions src/java/com/wolfssl/provider/jsse/WolfSSLImplementSSLSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -516,17 +516,13 @@ public synchronized Certificate[] getPeerCertificates()
"SSLSocket/Engine closed");
}

int numCerts;
try {
x509 = this.ssl.getPeerCertificate();
numCerts = this.ssl.getPeerCertificateCount();
} catch (IllegalStateException | WolfSSLJNIException ex) {
Logger.getLogger(
WolfSSLImplementSSLSession.class.getName()).log(
Level.SEVERE, null, ex);
x509 = 0;
}

/* if no peer cert, throw SSLPeerUnverifiedException */
if (x509 == 0) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"ssl.getPeerCertificates() returned null, trying cached cert");

Expand All @@ -542,56 +538,88 @@ public synchronized Certificate[] getPeerCertificates()
throw new SSLPeerUnverifiedException("No peer certificate");
}
}
X509Certificate[] certs = new X509Certificate[numCerts];

try {
/* wolfSSL starting with 5.3.0 returns a new WOLFSSL_X509
* structure from wolfSSL_get_peer_certificate(). In that case,
* we need to free the pointer when finished. Prior to 5.3.0,
* this memory was freed internally by wolfSSL since the API
* only returned a pointer to internal memory */
if (WolfSSL.getLibVersionHex() >= 0x05003000) {
cert = new WolfSSLX509(x509, true);
for (int i = 0; i < numCerts; i++) {
try {
x509 = this.ssl.getPeerCertificate(i);
} catch (IllegalStateException | WolfSSLJNIException ex) {
Logger.getLogger(
WolfSSLImplementSSLSession.class.getName()).log(
Level.SEVERE, null, ex);
x509 = 0;
}
else {
cert = new WolfSSLX509(x509, false);

/* if no peer cert, throw SSLPeerUnverifiedException */
if (x509 == 0) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"ssl.getPeerCertificates() returned null, trying cached cert");

if (this.peerCerts != null) {
/* If peer cert is already cached, just return that */
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"peer cert already cached, returning it");
return this.peerCerts.clone();
}
else {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"No peer cert sent and none cached");
throw new SSLPeerUnverifiedException("No peer certificate");
}
}
} catch (WolfSSLException ex) {
throw new SSLPeerUnverifiedException("Error creating certificate");
}

/* convert WolfSSLX509 into X509Certificate so we can release
* our native memory */
try {
cf = CertificateFactory.getInstance("X.509");
} catch (CertificateException ex) {
cert.free();
throw new SSLPeerUnverifiedException(
"Error getting CertificateFactory instance");
}
try {
/* wolfSSL starting with 5.3.0 returns a new WOLFSSL_X509
* structure from wolfSSL_get_peer_certificate(). In that case,
* we need to free the pointer when finished. Prior to 5.3.0,
* this memory was freed internally by wolfSSL since the API
* only returned a pointer to internal memory */
if (WolfSSL.getLibVersionHex() >= 0x05003000) {
cert = new WolfSSLX509(x509, true);
}
else {
cert = new WolfSSLX509(x509, false);
}
} catch (WolfSSLException ex) {
throw new SSLPeerUnverifiedException("Error creating certificate");
}

try {
der = new ByteArrayInputStream(cert.getEncoded());
} catch (CertificateEncodingException ex) {
cert.free();
throw new SSLPeerUnverifiedException(
"Error getting encoded DER from WolfSSLX509 object");
}
/* convert WolfSSLX509 into X509Certificate so we can release
* our native memory */
try {
cf = CertificateFactory.getInstance("X.509");
} catch (CertificateException ex) {
cert.free();
throw new SSLPeerUnverifiedException(
"Error getting CertificateFactory instance");
}

try {
exportCert = (X509Certificate)cf.generateCertificate(der);
} catch (CertificateException ex) {
try {
der = new ByteArrayInputStream(cert.getEncoded());
} catch (CertificateEncodingException ex) {
cert.free();
throw new SSLPeerUnverifiedException(
"Error getting encoded DER from WolfSSLX509 object");
}

try {
exportCert = (X509Certificate)cf.generateCertificate(der);
} catch (CertificateException ex) {
cert.free();
throw new SSLPeerUnverifiedException(
"Error generating X509Certificdate from DER encoding");
}

/* release native memory */
cert.free();
throw new SSLPeerUnverifiedException(
"Error generating X509Certificdate from DER encoding");
}

/* release native memory */
cert.free();
certs[i] = exportCert;
}

/* cache peer cert for use by app in resumed session */
this.peerCerts = new X509Certificate[] { exportCert };
this.peerCerts = certs;

return this.peerCerts.clone();
return certs.clone();
}

@Override
Expand All @@ -612,25 +640,30 @@ public synchronized javax.security.cert.X509Certificate[] getPeerCertificateChai
}

try {
peerX509 = this.ssl.getPeerCertificate();
if (peerX509 == 0) {
return null;
}
int numCerts = this.ssl.getPeerCertificateCount();
javax.security.cert.X509Certificate[] certs = new javax.security.cert.X509Certificate[numCerts];

/* wolfSSL starting with 5.3.0 returns a new WOLFSSL_X509
* structure from wolfSSL_get_peer_certificate(). In that case,
* we need to free the pointer when finished. Prior to 5.3.0,
* this memory was freed internally by wolfSSL since the API
* only returned a pointer to internal memory */
if (WolfSSL.getLibVersionHex() >= 0x05003000) {
x509 = new WolfSSLX509X(peerX509, true);
}
else {
x509 = new WolfSSLX509X(peerX509, false);
for (int i = 0; i < numCerts; i++) {
peerX509 = this.ssl.getPeerCertificate(i);
if (peerX509 == 0) {
return null;
}

/* wolfSSL starting with 5.3.0 returns a new WOLFSSL_X509
* structure from wolfSSL_get_peer_certificate(). In that case,
* we need to free the pointer when finished. Prior to 5.3.0,
* this memory was freed internally by wolfSSL since the API
* only returned a pointer to internal memory */
if (WolfSSL.getLibVersionHex() >= 0x05003000) {
x509 = new WolfSSLX509X(peerX509, true);
}
else {
x509 = new WolfSSLX509X(peerX509, false);
}
certs[i] = (javax.security.cert.X509Certificate)x509;
}

return new javax.security.cert.X509Certificate[] {
(javax.security.cert.X509Certificate)x509 };
return certs;

} catch (IllegalStateException | WolfSSLJNIException |
WolfSSLException ex) {
Expand All @@ -654,7 +687,7 @@ public synchronized Principal getPeerPrincipal()
}

try {
peerX509 = this.ssl.getPeerCertificate();
peerX509 = this.ssl.getPeerCertificate(0);
if (peerX509 == 0) {
return null;
}
Expand Down