Add CRL generation capability
parent
416029cd7d
commit
28b435518b
|
|
@ -350,6 +350,7 @@ add_library(wolfssljni SHARED
|
|||
${wolfssljni_DIR}/native/com_wolfssl_WolfSSLCertManager.c
|
||||
${wolfssljni_DIR}/native/com_wolfssl_WolfSSLCertRequest.c
|
||||
${wolfssljni_DIR}/native/com_wolfssl_WolfSSLCertificate.c
|
||||
${wolfssljni_DIR}/native/com_wolfssl_WolfSSLCRL.c
|
||||
${wolfssljni_DIR}/native/com_wolfssl_WolfSSLContext.c
|
||||
${wolfssljni_DIR}/native/com_wolfssl_WolfSSLSession.c
|
||||
${wolfssljni_DIR}/native/com_wolfssl_WolfSSLX509Name.c
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLCertificate.c" />
|
||||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLCertManager.c" />
|
||||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLCertRequest.c" />
|
||||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLCRL.c" />
|
||||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLContext.c" />
|
||||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLSession.c" />
|
||||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLX509Name.c" />
|
||||
|
|
@ -57,6 +58,7 @@
|
|||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLCertificate.h" />
|
||||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLCertManager.h" />
|
||||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLCertRequest.h" />
|
||||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLCRL.h" />
|
||||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLContext.h" />
|
||||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLSession.h" />
|
||||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLX509Name.h" />
|
||||
|
|
|
|||
|
|
@ -36,6 +36,9 @@
|
|||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLCertRequest.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLCRL.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLContext.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -80,6 +83,9 @@
|
|||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLCertRequest.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLCRL.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLContext.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@
|
|||
<class name="com.wolfssl.WolfSSL"/>
|
||||
<class name="com.wolfssl.WolfSSLCertManager"/>
|
||||
<class name="com.wolfssl.WolfSSLCertificate"/>
|
||||
<class name="com.wolfssl.WolfSSLCRL"/>
|
||||
<class name="com.wolfssl.WolfSSLContext"/>
|
||||
<class name="com.wolfssl.WolfSSLSession"/>
|
||||
<class name="com.wolfssl.WolfSSLX509StoreCtx"/>
|
||||
|
|
|
|||
2
java.sh
2
java.sh
|
|
@ -125,10 +125,12 @@ gcc -Wall -c $fpic $CFLAGS ./native/com_wolfssl_WolfCryptEccKey.c -o ./native/co
|
|||
gcc -Wall -c $fpic $CFLAGS ./native/com_wolfssl_WolfSSLCertManager.c -o ./native/com_wolfssl_WolfSSLCertManager.o $javaIncludes
|
||||
gcc -Wall -c $fpic $CFLAGS ./native/com_wolfssl_WolfSSLCertRequest.c -o ./native/com_wolfssl_WolfSSLCertRequest.o $javaIncludes
|
||||
gcc -Wall -c $fpic $CFLAGS ./native/com_wolfssl_WolfSSLCertificate.c -o ./native/com_wolfssl_WolfSSLCertificate.o $javaIncludes
|
||||
gcc -Wall -c $fpic $CFLAGS ./native/com_wolfssl_WolfSSLCRL.c -o ./native/com_wolfssl_WolfSSLCRL.o $javaIncludes
|
||||
gcc -Wall -c $fpic $CFLAGS ./native/com_wolfssl_WolfSSLX509Name.c -o ./native/com_wolfssl_WolfSSLX509Name.o $javaIncludes
|
||||
gcc -Wall -c $fpic $CFLAGS ./native/com_wolfssl_WolfSSLX509StoreCtx.c -o ./native/com_wolfssl_WolfSSLX509StoreCtx.o $javaIncludes
|
||||
gcc -Wall -c $fpic $CFLAGS ./native/com_wolfssl_WolfSSLNameConstraints.c -o ./native/com_wolfssl_WolfSSLNameConstraints.o $javaIncludes
|
||||
gcc -Wall $javaLibs $CFLAGS -o ./lib/$jniLibName ./native/com_wolfssl_WolfSSL.o ./native/com_wolfssl_WolfSSLSession.o ./native/com_wolfssl_WolfSSLContext.o ./native/com_wolfssl_WolfCryptRSA.o ./native/com_wolfssl_WolfCryptECC.o ./native/com_wolfssl_WolfCryptEccKey.o ./native/com_wolfssl_WolfSSLCertManager.o ./native/com_wolfssl_WolfSSLCertRequest.o ./native/com_wolfssl_WolfSSLCertificate.o ./native/com_wolfssl_WolfSSLX509Name.o ./native/com_wolfssl_WolfSSLX509StoreCtx.o ./native/com_wolfssl_WolfSSLNameConstraints.o -L$WOLFSSL_INSTALL_DIR/lib -L$WOLFSSL_INSTALL_DIR/lib64 -l$WOLFSSL_LIBNAME
|
||||
gcc -Wall $javaLibs $CFLAGS -o ./lib/$jniLibName ./native/com_wolfssl_WolfSSL.o ./native/com_wolfssl_WolfSSLSession.o ./native/com_wolfssl_WolfSSLContext.o ./native/com_wolfssl_WolfCryptRSA.o ./native/com_wolfssl_WolfCryptECC.o ./native/com_wolfssl_WolfCryptEccKey.o ./native/com_wolfssl_WolfSSLCertManager.o ./native/com_wolfssl_WolfSSLCertRequest.o ./native/com_wolfssl_WolfSSLCertificate.o ./native/com_wolfssl_WolfSSLCRL.o ./native/com_wolfssl_WolfSSLX509Name.o ./native/com_wolfssl_WolfSSLX509StoreCtx.o -L$WOLFSSL_INSTALL_DIR/lib -L$WOLFSSL_INSTALL_DIR/lib64 -l$WOLFSSL_LIBNAME
|
||||
if [ $? != 0 ]; then
|
||||
echo "Error creating native JNI library"
|
||||
exit 1
|
||||
|
|
|
|||
|
|
@ -0,0 +1,775 @@
|
|||
/* com_wolfssl_WolfSSLCRL.c
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef WOLFSSL_USER_SETTINGS
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#else
|
||||
#include <wolfssl/options.h>
|
||||
#endif
|
||||
#include <wolfssl/version.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <wolfssl/wolfcrypt/asn.h>
|
||||
#include <wolfssl/openssl/evp.h>
|
||||
#include <wolfssl/openssl/x509.h>
|
||||
#include <wolfssl/error-ssl.h>
|
||||
|
||||
#include "com_wolfssl_globals.h"
|
||||
#include "com_wolfssl_WolfSSLCRL.h"
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1new
|
||||
(JNIEnv* jenv, jclass jcl)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = NULL;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
crl = wolfSSL_X509_CRL_new();
|
||||
if (crl == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (jlong)(uintptr_t)crl;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1free
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
wolfSSL_X509_CRL_free(crl);
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1set_1version
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr, jint version)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
return wolfSSL_X509_CRL_set_version(crl, version);
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
(void)version;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1set_1issuer_1name
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr, jlong x509NamePtr)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
WOLFSSL_X509_NAME* name = (WOLFSSL_X509_NAME*)(uintptr_t)x509NamePtr;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL || name == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
return wolfSSL_X509_CRL_set_issuer_name(crl, name);
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
(void)x509NamePtr;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1set_1lastUpdate
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr, jbyteArray time)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
byte* timeBuf = NULL;
|
||||
int timeSz = 0;
|
||||
int ret = 0;
|
||||
WOLFSSL_ASN1_TIME asnTime;
|
||||
char timeStr[CTC_DATE_SIZE + 1];
|
||||
int timeLen = 0;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL || time == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
timeBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, time, NULL);
|
||||
timeSz = (*jenv)->GetArrayLength(jenv, time);
|
||||
/* Ensure there is enough room for date string (32 bytes)
|
||||
plus 4 bytes of length and 4 bytes for type. */
|
||||
if (timeBuf == NULL || timeSz < (CTC_DATE_SIZE + 8)) {
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
/* Extract length from bytes 32-35 (assuming native byte order) */
|
||||
timeLen = *((int*)(timeBuf + CTC_DATE_SIZE));
|
||||
if (timeLen <= 0 || timeLen > CTC_DATE_SIZE) {
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
/* Copy time string and null-terminate */
|
||||
XMEMCPY(timeStr, timeBuf, timeLen);
|
||||
timeStr[timeLen] = '\0';
|
||||
/* Create ASN1_TIME object and set string */
|
||||
if (wolfSSL_ASN1_TIME_set_string(&asnTime, timeStr) == 1) {
|
||||
ret = wolfSSL_X509_CRL_set_lastUpdate(crl, &asnTime);
|
||||
}
|
||||
else {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(*jenv)->ReleaseByteArrayElements(jenv, time, (jbyte*)timeBuf, JNI_ABORT);
|
||||
|
||||
return (jint)ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
(void)time;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1set_1nextUpdate
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr, jbyteArray time)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
byte* timeBuf = NULL;
|
||||
int timeSz = 0;
|
||||
int ret = 0;
|
||||
WOLFSSL_ASN1_TIME asnTime;
|
||||
char timeStr[CTC_DATE_SIZE + 1];
|
||||
int timeLen = 0;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL || time == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
timeBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, time, NULL);
|
||||
timeSz = (*jenv)->GetArrayLength(jenv, time);
|
||||
/* Ensure there is enough room for date string (32 bytes)
|
||||
plus 4 bytes of length and 4 bytes for type. */
|
||||
if (timeBuf == NULL || timeSz < (CTC_DATE_SIZE + 8)) {
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
/* Extract length from bytes 32-35 (assuming native byte order) */
|
||||
timeLen = *((int*)(timeBuf + CTC_DATE_SIZE));
|
||||
if (timeLen <= 0 || timeLen > CTC_DATE_SIZE) {
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
/* Copy time string and null-terminate */
|
||||
XMEMCPY(timeStr, timeBuf, timeLen);
|
||||
timeStr[timeLen] = '\0';
|
||||
/* Create ASN1_TIME object and set string */
|
||||
if (wolfSSL_ASN1_TIME_set_string(&asnTime, timeStr) == 1) {
|
||||
ret = wolfSSL_X509_CRL_set_nextUpdate(crl, &asnTime);
|
||||
}
|
||||
else {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(*jenv)->ReleaseByteArrayElements(jenv, time, (jbyte*)timeBuf, JNI_ABORT);
|
||||
|
||||
return (jint)ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
(void)time;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1add_1revoked
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr, jbyteArray serial,
|
||||
jbyteArray revDate, jint dateFmt)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
byte* serialBuf = NULL;
|
||||
byte* dateBuf = NULL;
|
||||
int serialSz = 0;
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL || serial == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
serialBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, serial, NULL);
|
||||
serialSz = (*jenv)->GetArrayLength(jenv, serial);
|
||||
if (serialBuf == NULL || serialSz == 0) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
if (revDate != NULL) {
|
||||
dateBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, revDate, NULL);
|
||||
if (dateBuf == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
if (ret != WOLFSSL_FAILURE) {
|
||||
ret = wolfSSL_X509_CRL_add_revoked(crl, serialBuf, serialSz,
|
||||
dateBuf, (unsigned char)dateFmt);
|
||||
}
|
||||
if (dateBuf != NULL) {
|
||||
(*jenv)->ReleaseByteArrayElements(jenv, revDate, (jbyte*)dateBuf,
|
||||
JNI_ABORT);
|
||||
}
|
||||
}
|
||||
|
||||
(*jenv)->ReleaseByteArrayElements(jenv, serial, (jbyte*)serialBuf,
|
||||
JNI_ABORT);
|
||||
|
||||
return ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
(void)serial;
|
||||
(void)revDate;
|
||||
(void)dateFmt;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1add_1revoked_1cert
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr, jbyteArray certDer,
|
||||
jbyteArray revDate, jint dateFmt)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
byte* certBuf = NULL;
|
||||
byte* dateBuf = NULL;
|
||||
int certSz = 0;
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL || certDer == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
certBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, certDer, NULL);
|
||||
certSz = (*jenv)->GetArrayLength(jenv, certDer);
|
||||
if (certBuf == NULL || certSz == 0) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
if (revDate != NULL) {
|
||||
dateBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, revDate, NULL);
|
||||
if (dateBuf == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
if (ret != WOLFSSL_FAILURE) {
|
||||
ret = wolfSSL_X509_CRL_add_revoked_cert(crl, certBuf, certSz,
|
||||
dateBuf, (unsigned char)dateFmt);
|
||||
}
|
||||
if (dateBuf != NULL) {
|
||||
(*jenv)->ReleaseByteArrayElements(jenv, revDate, (jbyte*)dateBuf,
|
||||
JNI_ABORT);
|
||||
}
|
||||
}
|
||||
|
||||
(*jenv)->ReleaseByteArrayElements(jenv, certDer, (jbyte*)certBuf,
|
||||
JNI_ABORT);
|
||||
|
||||
return ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
(void)certDer;
|
||||
(void)revDate;
|
||||
(void)dateFmt;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1sign
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr, jint keyType, jbyteArray keyBytes,
|
||||
jint format, jstring digestAlg)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
byte* keyBuf = NULL;
|
||||
int keySz = 0;
|
||||
byte* derBuf = NULL;
|
||||
int derSz = 0;
|
||||
WOLFSSL_EVP_PKEY* priv = NULL;
|
||||
const WOLFSSL_EVP_MD* md = NULL;
|
||||
unsigned char* rsaPrivBuf = NULL;
|
||||
const char* mdName = NULL;
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL || keyBytes == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
keyBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, keyBytes, NULL);
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
keySz = (*jenv)->GetArrayLength(jenv, keyBytes);
|
||||
|
||||
if (keyBuf == NULL || keySz == 0) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (digestAlg != NULL) {
|
||||
mdName = (*jenv)->GetStringUTFChars(jenv, digestAlg, 0);
|
||||
if (mdName == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
md = wolfSSL_EVP_get_digestbyname(mdName);
|
||||
if (md == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* convert PEM to DER if needed */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if ((int)format == WOLFSSL_FILETYPE_ASN1) {
|
||||
/* already in DER */
|
||||
derBuf = keyBuf;
|
||||
derSz = keySz;
|
||||
}
|
||||
else {
|
||||
/* get needed buffer size */
|
||||
ret = wc_KeyPemToDer(keyBuf, keySz, NULL, 0, NULL);
|
||||
if (ret <= 0) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
derSz = ret;
|
||||
derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (derBuf == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
XMEMSET(derBuf, 0, derSz);
|
||||
}
|
||||
}
|
||||
/* convert PEM to DER */
|
||||
if (derBuf != NULL && ret == WOLFSSL_SUCCESS) {
|
||||
ret = wc_KeyPemToDer(keyBuf, keySz, derBuf, derSz, NULL);
|
||||
if (ret <= 0 || ret != derSz) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* convert buffer into WOLFSSL_EVP_PKEY */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
/* Use temp pointer since d2i_PrivateKey() modifies the buffer */
|
||||
rsaPrivBuf = derBuf;
|
||||
|
||||
priv = wolfSSL_d2i_PrivateKey((int)keyType, NULL,
|
||||
(const unsigned char**)&rsaPrivBuf, derSz);
|
||||
if (priv == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* sign WOLFSSL_X509_CRL with WOLFSSL_EVP_PKEY, returns size of signature
|
||||
* on success or negative on error */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_X509_CRL_sign(crl, priv, md);
|
||||
if (ret >= 0) {
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv != NULL) {
|
||||
wolfSSL_EVP_PKEY_free(priv);
|
||||
}
|
||||
if (derBuf != NULL && derBuf != keyBuf) {
|
||||
XMEMSET(derBuf, 0, derSz);
|
||||
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
derBuf = NULL;
|
||||
}
|
||||
if (mdName != NULL) {
|
||||
(*jenv)->ReleaseStringUTFChars(jenv, digestAlg, mdName);
|
||||
}
|
||||
if (keyBuf != NULL) {
|
||||
(*jenv)->ReleaseByteArrayElements(jenv, keyBytes, (jbyte*)keyBuf,
|
||||
JNI_ABORT);
|
||||
}
|
||||
|
||||
return ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
(void)keyType;
|
||||
(void)keyBytes;
|
||||
(void)format;
|
||||
(void)digestAlg;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_write_1X509_1CRL
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr, jstring path, jint format)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
const char* cPath = NULL;
|
||||
int ret = WOLFSSL_FAILURE;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL || path == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
cPath = (*jenv)->GetStringUTFChars(jenv, path, NULL);
|
||||
if (cPath == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
ret = wolfSSL_write_X509_CRL(crl, cPath, format);
|
||||
|
||||
(*jenv)->ReleaseStringUTFChars(jenv, path, cPath);
|
||||
|
||||
return ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
(void)path;
|
||||
(void)format;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1version
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (jint)wolfSSL_X509_CRL_version(crl);
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1get_1lastUpdate
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && \
|
||||
defined(WOLFSSL_CERT_GEN) && !defined(NO_ASN_TIME)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
WOLFSSL_ASN1_TIME* date = NULL;
|
||||
char timeStr[CTC_DATE_SIZE];
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
date = wolfSSL_X509_CRL_get_lastUpdate(crl);
|
||||
if (date != NULL) {
|
||||
return (*jenv)->NewStringUTF(jenv,
|
||||
wolfSSL_ASN1_TIME_to_string(date, timeStr, sizeof(timeStr)));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1get_1nextUpdate
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && \
|
||||
defined(WOLFSSL_CERT_GEN) && !defined(NO_ASN_TIME)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
WOLFSSL_ASN1_TIME* date = NULL;
|
||||
char timeStr[CTC_DATE_SIZE];
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
date = wolfSSL_X509_CRL_get_nextUpdate(crl);
|
||||
if (date != NULL) {
|
||||
return (*jenv)->NewStringUTF(jenv,
|
||||
wolfSSL_ASN1_TIME_to_string(date, timeStr, sizeof(timeStr)));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1print
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_BIO* bio;
|
||||
int sz = 0;
|
||||
char* mem = NULL;
|
||||
jbyteArray memArr = NULL;
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wolfSSL_X509_CRL_print(bio, crl) != WOLFSSL_SUCCESS) {
|
||||
wolfSSL_BIO_free(bio);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sz = wolfSSL_BIO_get_mem_data(bio, &mem);
|
||||
if (sz > 0 && mem != NULL) {
|
||||
memArr = (*jenv)->NewByteArray(jenv, sz);
|
||||
if (memArr == NULL) {
|
||||
wolfSSL_BIO_free(bio);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(*jenv)->SetByteArrayRegion(jenv, memArr, 0, sz, (jbyte*)mem);
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->DeleteLocalRef(jenv, memArr);
|
||||
wolfSSL_BIO_free(bio);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
wolfSSL_BIO_free(bio);
|
||||
return memArr;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1get_1der
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
unsigned char* der = NULL;
|
||||
jbyteArray derArr = NULL;
|
||||
jclass excClass = NULL;
|
||||
int sz = 0;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sz = wolfSSL_i2d_X509_CRL(crl, &der);
|
||||
if (sz <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
derArr = (*jenv)->NewByteArray(jenv, sz);
|
||||
if (derArr == NULL) {
|
||||
(*jenv)->ThrowNew(jenv, jcl,
|
||||
"Failed to create byte array in native X509_CRL_get_der");
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLJNIException");
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->DeleteLocalRef(jenv, derArr);
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(*jenv)->SetByteArrayRegion(jenv, derArr, 0, sz, (jbyte*)der);
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->DeleteLocalRef(jenv, derArr);
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to set byte region in native X509_CRL_get_der");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
|
||||
return derArr;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1get_1pem
|
||||
(JNIEnv* jenv, jclass jcl, jlong crlPtr)
|
||||
{
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA) && defined(WOLFSSL_CERT_GEN)
|
||||
WOLFSSL_X509_CRL* crl = (WOLFSSL_X509_CRL*)(uintptr_t)crlPtr;
|
||||
unsigned char* der = NULL;
|
||||
unsigned char* pem = NULL;
|
||||
int sz = 0;
|
||||
int pemSz = 0;
|
||||
jbyteArray pemArr = NULL;
|
||||
jclass excClass = NULL;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || crl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sz = wolfSSL_i2d_X509_CRL(crl, &der);
|
||||
if (sz <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pemSz = wc_DerToPem(der, sz, NULL, 0, CRL_TYPE);
|
||||
if (pemSz < 0) {
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (pem == NULL) {
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
return NULL;
|
||||
}
|
||||
XMEMSET(pem, 0, pemSz);
|
||||
|
||||
pemSz = wc_DerToPem(der, sz, pem, pemSz, CRL_TYPE);
|
||||
if (pemSz < 0) {
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return NULL;
|
||||
}
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
|
||||
pemArr = (*jenv)->NewByteArray(jenv, pemSz);
|
||||
if (pemArr == NULL) {
|
||||
(*jenv)->ThrowNew(jenv, jcl,
|
||||
"Failed to create byte array in native X509_CRL_get_pem");
|
||||
XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLJNIException");
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->DeleteLocalRef(jenv, pemArr);
|
||||
XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(*jenv)->SetByteArrayRegion(jenv, pemArr, 0, pemSz, (jbyte*)pem);
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->DeleteLocalRef(jenv, pemArr);
|
||||
XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to set byte region in native X509_CRL_get_pem");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
return pemArr;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)crlPtr;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class com_wolfssl_WolfSSLCRL */
|
||||
|
||||
#ifndef _Included_com_wolfssl_WolfSSLCRL
|
||||
#define _Included_com_wolfssl_WolfSSLCRL
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#undef com_wolfssl_WolfSSLCRL_serialVersionUID
|
||||
#define com_wolfssl_WolfSSLCRL_serialVersionUID 1LL
|
||||
#undef com_wolfssl_WolfSSLCRL_ASN_UTC_TIME
|
||||
#define com_wolfssl_WolfSSLCRL_ASN_UTC_TIME 23L
|
||||
#undef com_wolfssl_WolfSSLCRL_ASN_GENERALIZED_TIME
|
||||
#define com_wolfssl_WolfSSLCRL_ASN_GENERALIZED_TIME 24L
|
||||
#undef com_wolfssl_WolfSSLCRL_CTC_DATE_SIZE
|
||||
#define com_wolfssl_WolfSSLCRL_CTC_DATE_SIZE 32L
|
||||
#undef com_wolfssl_WolfSSLCRL_ASN1_TIME_STRUCT_SIZE
|
||||
#define com_wolfssl_WolfSSLCRL_ASN1_TIME_STRUCT_SIZE 40L
|
||||
#undef com_wolfssl_WolfSSLCRL_ASN1_UTC_YEAR_MIN
|
||||
#define com_wolfssl_WolfSSLCRL_ASN1_UTC_YEAR_MIN 1950L
|
||||
#undef com_wolfssl_WolfSSLCRL_ASN1_UTC_YEAR_MAX
|
||||
#define com_wolfssl_WolfSSLCRL_ASN1_UTC_YEAR_MAX 2049L
|
||||
#undef com_wolfssl_WolfSSLCRL_EVP_PKEY_RSA
|
||||
#define com_wolfssl_WolfSSLCRL_EVP_PKEY_RSA 16L
|
||||
#undef com_wolfssl_WolfSSLCRL_EVP_PKEY_EC
|
||||
#define com_wolfssl_WolfSSLCRL_EVP_PKEY_EC 18L
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_new
|
||||
* Signature: ()J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1new
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_free
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1free
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_set_version
|
||||
* Signature: (JI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1set_1version
|
||||
(JNIEnv *, jclass, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_set_issuer_name
|
||||
* Signature: (JJ)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1set_1issuer_1name
|
||||
(JNIEnv *, jclass, jlong, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_set_lastUpdate
|
||||
* Signature: (J[B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1set_1lastUpdate
|
||||
(JNIEnv *, jclass, jlong, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_set_nextUpdate
|
||||
* Signature: (J[B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1set_1nextUpdate
|
||||
(JNIEnv *, jclass, jlong, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_add_revoked
|
||||
* Signature: (J[B[BI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1add_1revoked
|
||||
(JNIEnv *, jclass, jlong, jbyteArray, jbyteArray, jint);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_add_revoked_cert
|
||||
* Signature: (J[B[BI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1add_1revoked_1cert
|
||||
(JNIEnv *, jclass, jlong, jbyteArray, jbyteArray, jint);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_sign
|
||||
* Signature: (JI[BILjava/lang/String;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1sign
|
||||
(JNIEnv *, jclass, jlong, jint, jbyteArray, jint, jstring);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: write_X509_CRL
|
||||
* Signature: (JLjava/lang/String;I)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_write_1X509_1CRL
|
||||
(JNIEnv *, jclass, jlong, jstring, jint);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_print
|
||||
* Signature: (J)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1print
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_version
|
||||
* Signature: (J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1version
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_get_lastUpdate
|
||||
* Signature: (J)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1get_1lastUpdate
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_get_nextUpdate
|
||||
* Signature: (J)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1get_1nextUpdate
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_get_der
|
||||
* Signature: (J)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1get_1der
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCRL
|
||||
* Method: X509_CRL_get_pem
|
||||
* Signature: (J)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCRL_X509_1CRL_1get_1pem
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -1022,7 +1022,7 @@ JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1notBefore
|
|||
const unsigned char* date = NULL;
|
||||
#endif
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
|
||||
char ret[32];
|
||||
char timeStr[CTC_DATE_SIZE];
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || x509 == NULL) {
|
||||
|
|
@ -1037,8 +1037,8 @@ JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1notBefore
|
|||
/* returns string holding date i.e. "Thu Jan 07 08:23:09 MST 2021" */
|
||||
if (date != NULL) {
|
||||
return (*jenv)->NewStringUTF(jenv,
|
||||
wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)date, ret,
|
||||
sizeof(ret)));
|
||||
wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)date, timeStr,
|
||||
sizeof(timeStr)));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -1052,7 +1052,7 @@ JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1notAfter
|
|||
const unsigned char* date = NULL;
|
||||
#endif
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
|
||||
char ret[32];
|
||||
char timeStr[CTC_DATE_SIZE];
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || x509 == NULL) {
|
||||
|
|
@ -1068,7 +1068,7 @@ JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1notAfter
|
|||
if (date != NULL) {
|
||||
return (*jenv)->NewStringUTF(jenv,
|
||||
wolfSSL_ASN1_TIME_to_string((WOLFSSL_ASN1_TIME*)date,
|
||||
ret, sizeof(ret)));
|
||||
timeStr, sizeof(timeStr)));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ LOCAL_SRC_FILES := \
|
|||
native/com_wolfssl_WolfCryptRSA.c \
|
||||
native/com_wolfssl_WolfSSL.c \
|
||||
native/com_wolfssl_WolfSSLCertificate.c \
|
||||
native/com_wolfssl_WolfSSLCRL.c \
|
||||
native/com_wolfssl_WolfSSLCertManager.c \
|
||||
native/com_wolfssl_WolfSSLContext.c \
|
||||
native/com_wolfssl_WolfSSLSession.c \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,682 @@
|
|||
/* WolfSSLCRL.java
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
package com.wolfssl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.interfaces.ECPrivateKey;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
|
||||
/**
|
||||
* WolfSSLCRL class, wraps native wolfSSL WOLFSSL_X509_CRL functionality.
|
||||
*/
|
||||
public class WolfSSLCRL implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** Flag if this class is active or not */
|
||||
private boolean active = false;
|
||||
|
||||
/** Internal pointer for native WOLFSSL_X509_CRL */
|
||||
private long crlPtr = 0;
|
||||
|
||||
/** Does this WolfSSLCRL own the internal WOLFSSL_X509_CRL pointer? */
|
||||
private boolean weOwnCrlPtr = false;
|
||||
|
||||
/** lock around active state */
|
||||
private transient final Object stateLock = new Object();
|
||||
|
||||
/** lock around native WOLFSSL_X509_CRL pointer use */
|
||||
private transient final Object crlLock = new Object();
|
||||
|
||||
/* From wolfssl/wolfcrypt/asn.h and wolfssl/wolfcrypt/asn_public.h */
|
||||
private static final int ASN_UTC_TIME = 0x17;
|
||||
private static final int ASN_GENERALIZED_TIME = 0x18;
|
||||
private static final int CTC_DATE_SIZE = 32;
|
||||
private static final int ASN1_TIME_STRUCT_SIZE = CTC_DATE_SIZE + 8;
|
||||
private static final int ASN1_UTC_YEAR_MIN = 1950;
|
||||
private static final int ASN1_UTC_YEAR_MAX = 2049;
|
||||
private static final int EVP_PKEY_RSA = 16;
|
||||
private static final int EVP_PKEY_EC = 18;
|
||||
|
||||
/* Native method declarations */
|
||||
static native long X509_CRL_new();
|
||||
static native void X509_CRL_free(long crl);
|
||||
static native int X509_CRL_set_version(long crl, int version);
|
||||
static native int X509_CRL_set_issuer_name(long crl, long x509NamePtr);
|
||||
static native int X509_CRL_set_lastUpdate(long crl, byte[] time);
|
||||
static native int X509_CRL_set_nextUpdate(long crl, byte[] time);
|
||||
static native int X509_CRL_add_revoked(long crl, byte[] serial,
|
||||
byte[] revDate, int dateFmt);
|
||||
static native int X509_CRL_add_revoked_cert(long crl, byte[] certDer,
|
||||
byte[] revDate, int dateFmt);
|
||||
static native int X509_CRL_sign(long crl, int keyType, byte[] keyBytes,
|
||||
int format, String digestAlg);
|
||||
static native int write_X509_CRL(long crl, String path, int format);
|
||||
static native byte[] X509_CRL_print(long crl);
|
||||
static native int X509_CRL_version(long crl);
|
||||
static native String X509_CRL_get_lastUpdate(long crl);
|
||||
static native String X509_CRL_get_nextUpdate(long crl);
|
||||
static native byte[] X509_CRL_get_der(long crl);
|
||||
static native byte[] X509_CRL_get_pem(long crl);
|
||||
|
||||
private static final class Asn1TimeData {
|
||||
private final byte[] paddedData;
|
||||
private final int length;
|
||||
private final int type;
|
||||
|
||||
private Asn1TimeData(byte[] paddedData, int length, int type) {
|
||||
this.paddedData = paddedData;
|
||||
this.length = length;
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
private static Asn1TimeData buildAsn1TimeData(Date date) {
|
||||
if (date == null) {
|
||||
throw new IllegalArgumentException("Date is null");
|
||||
}
|
||||
|
||||
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"),
|
||||
Locale.US);
|
||||
cal.setTime(date);
|
||||
int year = cal.get(Calendar.YEAR);
|
||||
boolean useUtcTime = (year >= ASN1_UTC_YEAR_MIN &&
|
||||
year <= ASN1_UTC_YEAR_MAX);
|
||||
|
||||
String pattern = useUtcTime ? "yyMMddHHmmss'Z'" :
|
||||
"yyyyMMddHHmmss'Z'";
|
||||
int type = useUtcTime ? ASN_UTC_TIME : ASN_GENERALIZED_TIME;
|
||||
|
||||
SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.US);
|
||||
format.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
byte[] timeBytes = format.format(date).getBytes(
|
||||
StandardCharsets.US_ASCII);
|
||||
|
||||
if (timeBytes.length > CTC_DATE_SIZE) {
|
||||
throw new IllegalArgumentException(
|
||||
"ASN.1 time exceeds max size: " + timeBytes.length);
|
||||
}
|
||||
|
||||
byte[] padded = new byte[CTC_DATE_SIZE];
|
||||
System.arraycopy(timeBytes, 0, padded, 0, timeBytes.length);
|
||||
|
||||
return new Asn1TimeData(padded, timeBytes.length, type);
|
||||
}
|
||||
|
||||
private static byte[] buildAsn1TimeStruct(Date date) {
|
||||
Asn1TimeData timeData = buildAsn1TimeData(date);
|
||||
ByteBuffer buffer = ByteBuffer.allocate(ASN1_TIME_STRUCT_SIZE)
|
||||
.order(ByteOrder.nativeOrder());
|
||||
buffer.put(timeData.paddedData);
|
||||
buffer.position(CTC_DATE_SIZE);
|
||||
buffer.putInt(timeData.length);
|
||||
buffer.putInt(timeData.type);
|
||||
return buffer.array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new empty WolfSSLCRL object, for CRL generation.
|
||||
*
|
||||
* @throws WolfSSLException if native API call fails.
|
||||
*/
|
||||
public WolfSSLCRL() throws WolfSSLException {
|
||||
|
||||
crlPtr = X509_CRL_new();
|
||||
if (crlPtr == 0) {
|
||||
throw new WolfSSLException("Failed to create WolfSSLCRL");
|
||||
}
|
||||
|
||||
this.weOwnCrlPtr = true;
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, crlPtr,
|
||||
() -> "creating new WolfSSLCRL");
|
||||
|
||||
synchronized (stateLock) {
|
||||
this.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new WolfSSLCRL from DER-encoded byte array.
|
||||
*
|
||||
* @param der ASN.1/DER encoded CRL
|
||||
*
|
||||
* @throws WolfSSLException if CRL loading is not implemented.
|
||||
*/
|
||||
public WolfSSLCRL(byte[] der) throws WolfSSLException {
|
||||
throw new WolfSSLException("CRL loading from DER not implemented yet");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create WolfSSLCRL from file in specified format.
|
||||
*
|
||||
* @param filePath path to CRL file
|
||||
* @param format format of CRL, either WolfSSL.SSL_FILETYPE_ASN1 or
|
||||
* WolfSSL.SSL_FILETYPE_PEM
|
||||
*
|
||||
* @throws WolfSSLException if CRL loading is not implemented.
|
||||
*/
|
||||
public WolfSSLCRL(String filePath, int format) throws WolfSSLException {
|
||||
throw new WolfSSLException("CRL loading from file not implemented yet");
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the current WolfSSLCRL object is active.
|
||||
*
|
||||
* @throws IllegalStateException if object has been freed
|
||||
*/
|
||||
private void confirmObjectIsActive()
|
||||
throws IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (this.active == false) {
|
||||
throw new IllegalStateException(
|
||||
"WolfSSLCRL object has been freed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set CRL version (0 = v1, 1 = v2).
|
||||
*
|
||||
* @param version CRL version
|
||||
*
|
||||
* @return native wolfSSL return code
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
*/
|
||||
public int setVersion(int version) throws IllegalStateException {
|
||||
confirmObjectIsActive();
|
||||
synchronized (crlLock) {
|
||||
return X509_CRL_set_version(this.crlPtr, version);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set CRL issuer name from WolfSSLX509Name.
|
||||
*
|
||||
* @param name WolfSSLX509Name to set as issuer
|
||||
*
|
||||
* @return native wolfSSL return code
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
* @throws WolfSSLException if name is null.
|
||||
*/
|
||||
public int setIssuerName(WolfSSLX509Name name)
|
||||
throws IllegalStateException, WolfSSLException {
|
||||
|
||||
if (name == null) {
|
||||
throw new WolfSSLException("Issuer name is null");
|
||||
}
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (crlLock) {
|
||||
return X509_CRL_set_issuer_name(this.crlPtr,
|
||||
name.getNativeX509NamePtr());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set CRL last update date.
|
||||
*
|
||||
* @param date Date to set as last update time
|
||||
*
|
||||
* @return native wolfSSL return code (WolfSSL.SSL_SUCCESS on success)
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
* @throws IllegalArgumentException if date is null.
|
||||
*/
|
||||
public int setLastUpdate(Date date) {
|
||||
if (date == null) {
|
||||
throw new IllegalArgumentException("LastUpdate date is null");
|
||||
}
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
byte[] asnTime = buildAsn1TimeStruct(date);
|
||||
synchronized (crlLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.crlPtr,
|
||||
() -> "entered setLastUpdate(" + date + ")");
|
||||
int ret = X509_CRL_set_lastUpdate(this.crlPtr, asnTime);
|
||||
return (ret == 0) ? WolfSSL.SSL_FAILURE : WolfSSL.SSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set CRL next update date.
|
||||
*
|
||||
* @param date Date to set as next update time
|
||||
*
|
||||
* @return native wolfSSL return code (WolfSSL.SSL_SUCCESS on success)
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
* @throws IllegalArgumentException if date is null.
|
||||
*/
|
||||
public int setNextUpdate(Date date) {
|
||||
if (date == null) {
|
||||
throw new IllegalArgumentException("NextUpdate date is null");
|
||||
}
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
byte[] asnTime = buildAsn1TimeStruct(date);
|
||||
synchronized (crlLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.crlPtr,
|
||||
() -> "entered setNextUpdate(" + date + ")");
|
||||
int ret = X509_CRL_set_nextUpdate(this.crlPtr, asnTime);
|
||||
return (ret == 0) ? WolfSSL.SSL_FAILURE : WolfSSL.SSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add revoked certificate entry to CRL by serial number.
|
||||
*
|
||||
* @param serialNumber Serial number of revoked certificate
|
||||
* @param revocationDate Date when certificate was revoked, or null
|
||||
*
|
||||
* @return native wolfSSL return code
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
* @throws IllegalArgumentException if serialNumber is null or empty.
|
||||
*/
|
||||
public int addRevoked(byte[] serialNumber, Date revocationDate) {
|
||||
if (serialNumber == null || serialNumber.length == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Serial number is null or empty");
|
||||
}
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
byte[] revDateBytes = null;
|
||||
int dateFmt = 0;
|
||||
if (revocationDate != null) {
|
||||
Asn1TimeData timeData = buildAsn1TimeData(revocationDate);
|
||||
revDateBytes = timeData.paddedData;
|
||||
dateFmt = timeData.type;
|
||||
}
|
||||
|
||||
synchronized (crlLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.crlPtr,
|
||||
() -> "entered addRevoked(serial: " + serialNumber.length +
|
||||
", revocationDate: " + revocationDate + ")");
|
||||
return X509_CRL_add_revoked(this.crlPtr, serialNumber,
|
||||
revDateBytes, dateFmt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add revoked certificate entry to CRL from DER-encoded certificate.
|
||||
*
|
||||
* @param certDer DER-encoded certificate to add as revoked
|
||||
* @param revocationDate Date when certificate was revoked, or null
|
||||
*
|
||||
* @return native wolfSSL return code
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
* @throws IllegalArgumentException if certDer is null or empty.
|
||||
*/
|
||||
public int addRevokedCert(byte[] certDer, Date revocationDate) {
|
||||
if (certDer == null || certDer.length == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Certificate DER is null or empty");
|
||||
}
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
byte[] revDateBytes = null;
|
||||
int dateFmt = 0;
|
||||
if (revocationDate != null) {
|
||||
Asn1TimeData timeData = buildAsn1TimeData(revocationDate);
|
||||
revDateBytes = timeData.paddedData;
|
||||
dateFmt = timeData.type;
|
||||
}
|
||||
|
||||
synchronized (crlLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.crlPtr,
|
||||
() -> "entered addRevokedCert(der: " + certDer.length +
|
||||
", revocationDate: " + revocationDate + ")");
|
||||
return X509_CRL_add_revoked_cert(this.crlPtr, certDer,
|
||||
revDateBytes, dateFmt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add revoked certificate entry to CRL from WolfSSLCertificate object.
|
||||
*
|
||||
* @param cert WolfSSLCertificate object to add as revoked
|
||||
* @param revocationDate Date when certificate was revoked, or null
|
||||
*
|
||||
* @return native wolfSSL return code
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed or if
|
||||
* certificate DER encoding fails.
|
||||
* @throws IllegalArgumentException if cert is null.
|
||||
*/
|
||||
public int addRevokedCert(WolfSSLCertificate cert, Date revocationDate) {
|
||||
if (cert == null) {
|
||||
throw new IllegalArgumentException("Certificate is null");
|
||||
}
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (crlLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.crlPtr,
|
||||
() -> "entered addRevokedCert(cert, revocationDate: " +
|
||||
revocationDate + ")");
|
||||
}
|
||||
|
||||
byte[] certDer = null;
|
||||
try {
|
||||
certDer = cert.getDer();
|
||||
}
|
||||
catch (WolfSSLJNIException ex) {
|
||||
throw new IllegalStateException(
|
||||
"Failed to get certificate DER", ex);
|
||||
}
|
||||
|
||||
if (certDer == null || certDer.length == 0) {
|
||||
throw new IllegalStateException("Certificate DER is empty");
|
||||
}
|
||||
|
||||
return addRevokedCert(certDer, revocationDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign CRL with private key from PrivateKey object.
|
||||
*
|
||||
* @param key java.security.PrivateKey object containing private key,
|
||||
* must be of type RSAPrivateKey or ECPrivateKey
|
||||
* @param digestAlg Message digest algorithm to use for signature
|
||||
* generation. Options include the following, but native algorithm
|
||||
* must be compiled into wolfSSL to be available:
|
||||
* "MD4", "MD5", "SHA1", "SHA224", "SHA256", "SHA384",
|
||||
* "SHA512", "SHA3_224", "SHA3_256", "SHA3_384", "SHA3_512"
|
||||
*
|
||||
* @return native wolfSSL return code (WolfSSL.SSL_SUCCESS on success)
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
* @throws IllegalArgumentException if key is null, unsupported key type,
|
||||
* or key does not support encoding.
|
||||
*/
|
||||
public int sign(PrivateKey key, String digestAlg) {
|
||||
int ret = 0;
|
||||
int evpKeyType;
|
||||
byte[] encodedKey = null;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (crlLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.crlPtr,
|
||||
() -> "entered sign(" + key + ", digestAlg: " + digestAlg +
|
||||
")");
|
||||
}
|
||||
|
||||
if (key == null) {
|
||||
throw new IllegalArgumentException("Key object is null");
|
||||
}
|
||||
|
||||
if (key instanceof RSAPrivateKey) {
|
||||
evpKeyType = EVP_PKEY_RSA;
|
||||
}
|
||||
else if (key instanceof ECPrivateKey) {
|
||||
evpKeyType = EVP_PKEY_EC;
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(
|
||||
"PrivateKey must be of type RSAPrivateKey or ECPrivateKey");
|
||||
}
|
||||
|
||||
/* Get DER encoded key */
|
||||
encodedKey = key.getEncoded();
|
||||
if (encodedKey == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"PrivateKey does not support encoding");
|
||||
}
|
||||
|
||||
synchronized (crlLock) {
|
||||
ret = X509_CRL_sign(this.crlPtr, evpKeyType, encodedKey,
|
||||
WolfSSL.SSL_FILETYPE_ASN1, digestAlg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write CRL to file in specified format.
|
||||
*
|
||||
* @param path path to file where CRL should be written
|
||||
* @param format format of CRL, either WolfSSL.SSL_FILETYPE_ASN1 or
|
||||
* WolfSSL.SSL_FILETYPE_PEM
|
||||
*
|
||||
* @return native wolfSSL return code (WolfSSL.SSL_SUCCESS on success)
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
* @throws IllegalArgumentException if path is null or empty, or format
|
||||
* is invalid.
|
||||
*/
|
||||
public int writeToFile(String path, int format) {
|
||||
if (path == null || path.length() == 0) {
|
||||
throw new IllegalArgumentException("Path is null or empty");
|
||||
}
|
||||
|
||||
if (format != WolfSSL.SSL_FILETYPE_ASN1 &&
|
||||
format != WolfSSL.SSL_FILETYPE_PEM) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid file format, must be PEM or DER");
|
||||
}
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (crlLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.crlPtr,
|
||||
() -> "entered writeToFile(" + path + ", format: " + format +
|
||||
")");
|
||||
|
||||
return write_X509_CRL(this.crlPtr, path, format);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ASN.1/DER encoding of this CRL.
|
||||
*
|
||||
* @return DER encoded array of CRL or null if not available.
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
* @throws WolfSSLJNIException if native JNI error occurs.
|
||||
*/
|
||||
public byte[] getDer() throws IllegalStateException, WolfSSLJNIException {
|
||||
confirmObjectIsActive();
|
||||
synchronized (crlLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.crlPtr, () -> "entered getDer()");
|
||||
return X509_CRL_get_der(this.crlPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PEM encoding of this CRL.
|
||||
*
|
||||
* @return PEM encoded array of CRL or null if not available.
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
* @throws WolfSSLJNIException if native JNI error occurs.
|
||||
*/
|
||||
public byte[] getPem() throws IllegalStateException, WolfSSLJNIException {
|
||||
confirmObjectIsActive();
|
||||
synchronized (crlLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.crlPtr, () -> "entered getPem()");
|
||||
return X509_CRL_get_pem(this.crlPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CRL version.
|
||||
*
|
||||
* @return version of CRL (0 = v1, 1 = v2)
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
*/
|
||||
public int getVersion() {
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (crlLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.crlPtr, () -> "entered getVersion()");
|
||||
|
||||
return X509_CRL_version(this.crlPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CRL last update date.
|
||||
*
|
||||
* @return last update date as Date object, or null if not available
|
||||
* or if date parsing fails.
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
*/
|
||||
public Date getLastUpdate() {
|
||||
String date;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (crlLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.crlPtr,
|
||||
() -> "entered getLastUpdate()");
|
||||
|
||||
date = X509_CRL_get_lastUpdate(this.crlPtr);
|
||||
}
|
||||
|
||||
if (date != null) {
|
||||
SimpleDateFormat format =
|
||||
new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz");
|
||||
try {
|
||||
return format.parse(date);
|
||||
} catch (ParseException ex) {
|
||||
/* error case parsing date */
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CRL next update date.
|
||||
*
|
||||
* @return next update date as Date object, or null if not available
|
||||
* or if date parsing fails.
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCRL has been freed.
|
||||
*/
|
||||
public Date getNextUpdate() {
|
||||
String date;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (crlLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, this.crlPtr,
|
||||
() -> "entered getNextUpdate()");
|
||||
|
||||
date = X509_CRL_get_nextUpdate(this.crlPtr);
|
||||
}
|
||||
|
||||
if (date != null) {
|
||||
SimpleDateFormat format =
|
||||
new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz");
|
||||
try {
|
||||
return format.parse(date);
|
||||
} catch (ParseException ex) {
|
||||
/* error case parsing date */
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
byte[] crlText = null;
|
||||
synchronized (stateLock) {
|
||||
if (this.active == false) {
|
||||
return super.toString();
|
||||
}
|
||||
synchronized (crlLock) {
|
||||
crlText = X509_CRL_print(this.crlPtr);
|
||||
}
|
||||
if (crlText != null) {
|
||||
/* let Java do the modified UTF-8 conversion */
|
||||
return new String(crlText, Charset.forName("UTF-8"));
|
||||
} else {
|
||||
System.out.println("toString: crlText == null");
|
||||
}
|
||||
}
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Free native CRL resources.
|
||||
*/
|
||||
public synchronized void free() {
|
||||
synchronized (stateLock) {
|
||||
if (!this.active) {
|
||||
return;
|
||||
}
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
if (this.weOwnCrlPtr) {
|
||||
synchronized (crlLock) {
|
||||
X509_CRL_free(this.crlPtr);
|
||||
this.crlPtr = 0;
|
||||
this.weOwnCrlPtr = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
this.free();
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,939 @@
|
|||
/* WolfSSLCRLTest.java
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
package com.wolfssl.test;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.BeforeClass;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import java.security.PrivateKey;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.Date;
|
||||
import java.util.Calendar;
|
||||
|
||||
import com.wolfssl.WolfSSL;
|
||||
import com.wolfssl.WolfSSLX509Name;
|
||||
import com.wolfssl.WolfSSLCRL;
|
||||
import com.wolfssl.WolfSSLCertificate;
|
||||
import com.wolfssl.WolfSSLException;
|
||||
import com.wolfssl.WolfSSLJNIException;
|
||||
|
||||
/**
|
||||
* @author wolfSSL
|
||||
*/
|
||||
public class WolfSSLCRLTest {
|
||||
public final static int TEST_FAIL = -1;
|
||||
public final static int TEST_SUCCESS = 0;
|
||||
|
||||
public static String caKeyDer = "examples/certs/ca-key.der";
|
||||
public static String caKeyPem = "examples/certs/ca-key.pem";
|
||||
public static String caCertPem = "examples/certs/ca-cert.pem";
|
||||
public static String clientCertPem = "examples/certs/client-cert.pem";
|
||||
public static String clientKeyDer = "examples/certs/client-key.der";
|
||||
public static String clientKeyPem = "examples/certs/client-key.pem";
|
||||
public static String eccCaKeyPem = "examples/certs/ca-ecc-key.pem";
|
||||
public static String eccClientKeyPem = "examples/certs/ecc-client-key.pem";
|
||||
|
||||
@BeforeClass
|
||||
public static void setCertPaths() throws WolfSSLException {
|
||||
|
||||
System.out.println("WolfSSLCRL Class");
|
||||
|
||||
try {
|
||||
WolfSSL.loadLibrary();
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
fail("failed to load native JNI library");
|
||||
}
|
||||
|
||||
caKeyDer = WolfSSLTestCommon.getPath(caKeyDer);
|
||||
caKeyPem = WolfSSLTestCommon.getPath(caKeyPem);
|
||||
caCertPem = WolfSSLTestCommon.getPath(caCertPem);
|
||||
clientCertPem = WolfSSLTestCommon.getPath(clientCertPem);
|
||||
clientKeyDer = WolfSSLTestCommon.getPath(clientKeyDer);
|
||||
clientKeyPem = WolfSSLTestCommon.getPath(clientKeyPem);
|
||||
eccCaKeyPem = WolfSSLTestCommon.getPath(eccCaKeyPem);
|
||||
eccClientKeyPem = WolfSSLTestCommon.getPath(eccClientKeyPem);
|
||||
}
|
||||
|
||||
/* Internal helper method, generate test IssuerName for CRL generation */
|
||||
private WolfSSLX509Name GenerateTestIssuerName() throws WolfSSLException {
|
||||
|
||||
WolfSSLX509Name name = new WolfSSLX509Name();
|
||||
|
||||
name.setCountryName("US");
|
||||
name.setStateOrProvinceName("Montana");
|
||||
name.setLocalityName("Bozeman");
|
||||
name.setCommonName("wolfSSL Test CA");
|
||||
name.setEmailAddress("support@wolfssl.com");
|
||||
name.setOrganizationName("wolfSSL Inc.");
|
||||
name.setOrganizationalUnitName("Development Test");
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetVersion()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\tsetVersion()");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Test setting valid versions */
|
||||
int ret = crl.setVersion(0);
|
||||
assertTrue("setVersion(0) should succeed", ret >= 0);
|
||||
ret = crl.setVersion(1);
|
||||
assertTrue("setVersion(1) should succeed", ret >= 0);
|
||||
|
||||
/* Verify version was set */
|
||||
int version = crl.getVersion();
|
||||
assertEquals(1, version);
|
||||
|
||||
/* Negative versions should still work (native handles validation) */
|
||||
ret = crl.setVersion(-100);
|
||||
/* Native may or may not validate, so just check it doesn't crash */
|
||||
|
||||
crl.free();
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetIssuerName()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\tsetIssuerName()");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Set issuer name */
|
||||
WolfSSLX509Name issuerName = GenerateTestIssuerName();
|
||||
assertNotNull(issuerName);
|
||||
int ret = crl.setIssuerName(issuerName);
|
||||
assertTrue("setIssuerName should succeed", ret >= 0);
|
||||
|
||||
/* Test null issuer name */
|
||||
try {
|
||||
crl.setIssuerName(null);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("null issuer name should throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Free native memory */
|
||||
issuerName.free();
|
||||
crl.free();
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetLastUpdate()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\tsetLastUpdate()");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Set last update date */
|
||||
Date now = new Date();
|
||||
int ret = crl.setLastUpdate(now);
|
||||
assertEquals(WolfSSL.SSL_SUCCESS, ret);
|
||||
|
||||
/* Verify date was set */
|
||||
Date retrieved = crl.getLastUpdate();
|
||||
assertNotNull(retrieved);
|
||||
/* Allow some tolerance for date comparison */
|
||||
long diff = Math.abs(retrieved.getTime() - now.getTime());
|
||||
assertTrue("Date should be within 1 second", diff < 1000);
|
||||
|
||||
/* Test null date */
|
||||
try {
|
||||
crl.setLastUpdate(null);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("null date should throw exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
crl.free();
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetNextUpdate()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\tsetNextUpdate()");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Set next update date */
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DAY_OF_YEAR, 30); /* 30 days from now */
|
||||
Date nextUpdate = cal.getTime();
|
||||
int ret = crl.setNextUpdate(nextUpdate);
|
||||
assertEquals(WolfSSL.SSL_SUCCESS, ret);
|
||||
|
||||
/* Verify date was set */
|
||||
Date retrieved = crl.getNextUpdate();
|
||||
assertNotNull(retrieved);
|
||||
/* Allow some tolerance for date comparison */
|
||||
long diff = Math.abs(retrieved.getTime() - nextUpdate.getTime());
|
||||
assertTrue("Date should be within 1 second", diff < 1000);
|
||||
|
||||
/* Test null date */
|
||||
try {
|
||||
crl.setNextUpdate(null);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("null date should throw exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
crl.free();
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddRevoked()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\taddRevoked()");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Add revoked certificate by serial number */
|
||||
byte[] serial1 = new byte[] { 0x01, 0x02, 0x03, 0x04 };
|
||||
Date revDate1 = new Date();
|
||||
int ret = crl.addRevoked(serial1, revDate1);
|
||||
assertTrue("addRevoked should succeed", ret >= 0);
|
||||
|
||||
/* Add another revoked certificate */
|
||||
byte[] serial2 = new byte[] { 0x05, 0x06, 0x07, 0x08 };
|
||||
Date revDate2 = new Date();
|
||||
ret = crl.addRevoked(serial2, revDate2);
|
||||
assertTrue("addRevoked should succeed", ret >= 0);
|
||||
|
||||
/* Add revoked certificate without revocation date */
|
||||
byte[] serial3 = new byte[] { 0x09, 0x0A, 0x0B, 0x0C };
|
||||
ret = crl.addRevoked(serial3, null);
|
||||
assertTrue("addRevoked should succeed", ret >= 0);
|
||||
|
||||
/* Test null serial number */
|
||||
try {
|
||||
crl.addRevoked(null, new Date());
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("null serial number should throw exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Test empty serial number */
|
||||
try {
|
||||
crl.addRevoked(new byte[0], new Date());
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("empty serial number should throw exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
crl.free();
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddRevokedCert_ByteArray()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\taddRevokedCert(byte[])");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Load certificate from PEM file and convert to DER */
|
||||
WolfSSLCertificate cert = new WolfSSLCertificate(clientCertPem,
|
||||
WolfSSL.SSL_FILETYPE_PEM);
|
||||
assertNotNull(cert);
|
||||
byte[] certDer = cert.getDer();
|
||||
assertNotNull(certDer);
|
||||
assertTrue(certDer.length > 0);
|
||||
|
||||
/* Add revoked certificate by DER */
|
||||
Date revDate = new Date();
|
||||
int ret = crl.addRevokedCert(certDer, revDate);
|
||||
assertTrue("addRevokedCert should succeed", ret >= 0);
|
||||
|
||||
/* Add revoked certificate without revocation date */
|
||||
ret = crl.addRevokedCert(certDer, null);
|
||||
assertTrue("addRevokedCert should succeed", ret >= 0);
|
||||
|
||||
/* Test null certificate DER */
|
||||
try {
|
||||
crl.addRevokedCert((byte[])null, new Date());
|
||||
System.out.println("\t\t... failed");
|
||||
fail("null certificate DER should throw exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Test empty certificate DER */
|
||||
try {
|
||||
crl.addRevokedCert(new byte[0], new Date());
|
||||
System.out.println("\t\t... failed");
|
||||
fail("empty certificate DER should throw exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
crl.free();
|
||||
System.out.println("\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddRevokedCert_WolfSSLCertificate()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\taddRevokedCert(WolfSSLCertificate)");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Load certificate */
|
||||
WolfSSLCertificate cert = new WolfSSLCertificate(clientCertPem,
|
||||
WolfSSL.SSL_FILETYPE_PEM);
|
||||
assertNotNull(cert);
|
||||
|
||||
/* Add revoked certificate */
|
||||
Date revDate = new Date();
|
||||
int ret = crl.addRevokedCert(cert, revDate);
|
||||
assertTrue("addRevokedCert should succeed", ret >= 0);
|
||||
|
||||
/* Add revoked certificate without revocation date */
|
||||
WolfSSLCertificate cert2 = new WolfSSLCertificate(clientCertPem,
|
||||
WolfSSL.SSL_FILETYPE_PEM);
|
||||
ret = crl.addRevokedCert(cert2, null);
|
||||
assertTrue("addRevokedCert should succeed", ret >= 0);
|
||||
|
||||
/* Test null certificate */
|
||||
try {
|
||||
crl.addRevokedCert((WolfSSLCertificate)null, new Date());
|
||||
System.out.println("\t... failed");
|
||||
fail("null certificate should throw exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Free native memory */
|
||||
cert.free();
|
||||
cert2.free();
|
||||
crl.free();
|
||||
System.out.println("\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSign_PrivateKey()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
|
||||
System.out.print("\tsign(PrivateKey)");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Set issuer name */
|
||||
WolfSSLX509Name issuerName = GenerateTestIssuerName();
|
||||
crl.setIssuerName(issuerName);
|
||||
|
||||
/* Set dates */
|
||||
crl.setLastUpdate(new Date());
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DAY_OF_YEAR, 30);
|
||||
crl.setNextUpdate(cal.getTime());
|
||||
|
||||
/* Add revoked certificate */
|
||||
byte[] serial = new byte[] { 0x01, 0x02, 0x03, 0x04 };
|
||||
crl.addRevoked(serial, new Date());
|
||||
|
||||
/* Sign with RSA key from file */
|
||||
byte[] keyBytes = Files.readAllBytes(Paths.get(caKeyDer));
|
||||
/* Note: sign() method expects PrivateKey object, not byte array */
|
||||
/* We'll test with generated key pair instead */
|
||||
|
||||
/* Generate RSA key pair */
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
|
||||
kpg.initialize(2048);
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
PrivateKey privKey = keyPair.getPrivate();
|
||||
|
||||
/* Sign CRL */
|
||||
int ret = crl.sign(privKey, "SHA256");
|
||||
assertTrue("sign should succeed", ret >= 0);
|
||||
|
||||
/* Test null private key */
|
||||
try {
|
||||
crl.sign(null, "SHA256");
|
||||
System.out.println("\t\t... failed");
|
||||
fail("null private key should throw exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Free native memory */
|
||||
issuerName.free();
|
||||
crl.free();
|
||||
System.out.println("\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteToFile()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
|
||||
System.out.print("\twriteToFile()");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Set issuer name */
|
||||
WolfSSLX509Name issuerName = GenerateTestIssuerName();
|
||||
crl.setIssuerName(issuerName);
|
||||
|
||||
/* Set dates */
|
||||
crl.setLastUpdate(new Date());
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DAY_OF_YEAR, 30);
|
||||
crl.setNextUpdate(cal.getTime());
|
||||
|
||||
/* Add revoked certificate */
|
||||
byte[] serial = new byte[] { 0x01, 0x02, 0x03, 0x04 };
|
||||
crl.addRevoked(serial, new Date());
|
||||
|
||||
/* Sign CRL */
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
|
||||
kpg.initialize(2048);
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
PrivateKey privKey = keyPair.getPrivate();
|
||||
crl.sign(privKey, "SHA256");
|
||||
|
||||
/* Write to DER file */
|
||||
File tempDer = File.createTempFile("test_crl_", ".der");
|
||||
int ret = crl.writeToFile(tempDer.getAbsolutePath(),
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
assertTrue("writeToFile DER should succeed", ret >= 0);
|
||||
assertTrue(tempDer.exists());
|
||||
assertTrue(tempDer.length() > 0);
|
||||
tempDer.delete();
|
||||
|
||||
/* Write to PEM file */
|
||||
File tempPem = File.createTempFile("test_crl_", ".pem");
|
||||
ret = crl.writeToFile(tempPem.getAbsolutePath(),
|
||||
WolfSSL.SSL_FILETYPE_PEM);
|
||||
assertTrue("writeToFile PEM should succeed", ret >= 0);
|
||||
assertTrue(tempPem.exists());
|
||||
assertTrue(tempPem.length() > 0);
|
||||
tempPem.delete();
|
||||
|
||||
/* Test null path */
|
||||
try {
|
||||
crl.writeToFile(null, WolfSSL.SSL_FILETYPE_PEM);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("null path should throw exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Test empty path */
|
||||
try {
|
||||
crl.writeToFile("", WolfSSL.SSL_FILETYPE_PEM);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("empty path should throw exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Test invalid format */
|
||||
try {
|
||||
crl.writeToFile("test.der", 12345);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("invalid format should throw exception");
|
||||
} catch (IllegalArgumentException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Free native memory */
|
||||
issuerName.free();
|
||||
crl.free();
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetDer()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
|
||||
System.out.print("\tgetDer()");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Set issuer name */
|
||||
WolfSSLX509Name issuerName = GenerateTestIssuerName();
|
||||
crl.setIssuerName(issuerName);
|
||||
|
||||
/* Set dates */
|
||||
crl.setLastUpdate(new Date());
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DAY_OF_YEAR, 30);
|
||||
crl.setNextUpdate(cal.getTime());
|
||||
|
||||
/* Add revoked certificate */
|
||||
byte[] serial = new byte[] { 0x01, 0x02, 0x03, 0x04 };
|
||||
crl.addRevoked(serial, new Date());
|
||||
|
||||
/* Sign CRL */
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
|
||||
kpg.initialize(2048);
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
PrivateKey privKey = keyPair.getPrivate();
|
||||
crl.sign(privKey, "SHA256");
|
||||
|
||||
/* Get DER encoding */
|
||||
byte[] der = crl.getDer();
|
||||
assertNotNull(der);
|
||||
assertTrue(der.length > 0);
|
||||
|
||||
/* Free native memory */
|
||||
issuerName.free();
|
||||
crl.free();
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPem()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
|
||||
System.out.print("\tgetPem()");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Set issuer name */
|
||||
WolfSSLX509Name issuerName = GenerateTestIssuerName();
|
||||
crl.setIssuerName(issuerName);
|
||||
|
||||
/* Set dates */
|
||||
crl.setLastUpdate(new Date());
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DAY_OF_YEAR, 30);
|
||||
crl.setNextUpdate(cal.getTime());
|
||||
|
||||
/* Add revoked certificate */
|
||||
byte[] serial = new byte[] { 0x01, 0x02, 0x03, 0x04 };
|
||||
crl.addRevoked(serial, new Date());
|
||||
|
||||
/* Sign CRL */
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
|
||||
kpg.initialize(2048);
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
PrivateKey privKey = keyPair.getPrivate();
|
||||
crl.sign(privKey, "SHA256");
|
||||
|
||||
/* Get PEM encoding */
|
||||
byte[] pem = crl.getPem();
|
||||
assertNotNull(pem);
|
||||
assertTrue(pem.length > 0);
|
||||
/* PEM should contain BEGIN/END markers */
|
||||
String pemStr = new String(pem);
|
||||
assertTrue(pemStr.contains("BEGIN"));
|
||||
assertTrue(pemStr.contains("CRL"));
|
||||
|
||||
/* Free native memory */
|
||||
issuerName.free();
|
||||
crl.free();
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetVersion()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\tgetVersion()");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Default version should be 2 (v3) */
|
||||
int version = crl.getVersion();
|
||||
if (version != 2) {
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("Default version should be 2 (v3)");
|
||||
}
|
||||
|
||||
/* Set version to 1 (v2) */
|
||||
crl.setVersion(1);
|
||||
version = crl.getVersion();
|
||||
if (version != 1) {
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("Version should be 1 (v2)");
|
||||
}
|
||||
|
||||
crl.free();
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenCRL_UsingFiles()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
|
||||
System.out.print("\tgen CRL using files");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Set version */
|
||||
crl.setVersion(1);
|
||||
|
||||
/* Set issuer name */
|
||||
WolfSSLX509Name issuerName = GenerateTestIssuerName();
|
||||
assertNotNull(issuerName);
|
||||
crl.setIssuerName(issuerName);
|
||||
|
||||
/* Set dates */
|
||||
Date lastUpdate = new Date();
|
||||
crl.setLastUpdate(lastUpdate);
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DAY_OF_YEAR, 30);
|
||||
Date nextUpdate = cal.getTime();
|
||||
crl.setNextUpdate(nextUpdate);
|
||||
|
||||
/* Add revoked certificates by serial number */
|
||||
byte[] serial1 = new byte[] { 0x01, 0x02, 0x03, 0x04 };
|
||||
Date revDate1 = new Date();
|
||||
crl.addRevoked(serial1, revDate1);
|
||||
|
||||
byte[] serial2 = new byte[] { 0x05, 0x06, 0x07, 0x08 };
|
||||
Date revDate2 = new Date();
|
||||
crl.addRevoked(serial2, revDate2);
|
||||
|
||||
/* Sign CRL with RSA key */
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
|
||||
kpg.initialize(2048);
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
PrivateKey privKey = keyPair.getPrivate();
|
||||
crl.sign(privKey, "SHA256");
|
||||
|
||||
/* Output to DER and PEM */
|
||||
byte[] derCrl = crl.getDer();
|
||||
byte[] pemCrl = crl.getPem();
|
||||
|
||||
assertNotNull(derCrl);
|
||||
assertTrue(derCrl.length > 0);
|
||||
assertNotNull(pemCrl);
|
||||
assertTrue(pemCrl.length > 0);
|
||||
|
||||
/* Verify version */
|
||||
int version = crl.getVersion();
|
||||
assertEquals(1, version);
|
||||
|
||||
/* Verify dates */
|
||||
Date retrievedLastUpdate = crl.getLastUpdate();
|
||||
assertNotNull(retrievedLastUpdate);
|
||||
Date retrievedNextUpdate = crl.getNextUpdate();
|
||||
assertNotNull(retrievedNextUpdate);
|
||||
|
||||
/* Free native memory */
|
||||
issuerName.free();
|
||||
crl.free();
|
||||
|
||||
System.out.println("\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenCRL_UsingCertificates()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
|
||||
System.out.print("\tgen CRL using certificates");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Set version */
|
||||
crl.setVersion(1);
|
||||
|
||||
/* Set issuer name */
|
||||
WolfSSLX509Name issuerName = GenerateTestIssuerName();
|
||||
assertNotNull(issuerName);
|
||||
crl.setIssuerName(issuerName);
|
||||
|
||||
/* Set dates */
|
||||
Date lastUpdate = new Date();
|
||||
crl.setLastUpdate(lastUpdate);
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DAY_OF_YEAR, 30);
|
||||
Date nextUpdate = cal.getTime();
|
||||
crl.setNextUpdate(nextUpdate);
|
||||
|
||||
/* Add revoked certificates using WolfSSLCertificate objects */
|
||||
WolfSSLCertificate cert1 = new WolfSSLCertificate(clientCertPem,
|
||||
WolfSSL.SSL_FILETYPE_PEM);
|
||||
Date revDate1 = new Date();
|
||||
crl.addRevokedCert(cert1, revDate1);
|
||||
|
||||
/* Sign CRL with RSA key */
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
|
||||
kpg.initialize(2048);
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
PrivateKey privKey = keyPair.getPrivate();
|
||||
crl.sign(privKey, "SHA256");
|
||||
|
||||
/* Output to DER and PEM */
|
||||
byte[] derCrl = crl.getDer();
|
||||
byte[] pemCrl = crl.getPem();
|
||||
|
||||
assertNotNull(derCrl);
|
||||
assertTrue(derCrl.length > 0);
|
||||
assertNotNull(pemCrl);
|
||||
assertTrue(pemCrl.length > 0);
|
||||
|
||||
/* Free native memory */
|
||||
cert1.free();
|
||||
issuerName.free();
|
||||
crl.free();
|
||||
|
||||
System.out.println("\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenCRL_ECC()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
|
||||
System.out.print("\tgen CRL with ECC key");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!WolfSSL.EccEnabled()) {
|
||||
System.out.println("\t\t... skipped (ECC not enabled)");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Set version */
|
||||
crl.setVersion(1);
|
||||
|
||||
/* Set issuer name */
|
||||
WolfSSLX509Name issuerName = GenerateTestIssuerName();
|
||||
assertNotNull(issuerName);
|
||||
crl.setIssuerName(issuerName);
|
||||
|
||||
/* Set dates */
|
||||
Date lastUpdate = new Date();
|
||||
crl.setLastUpdate(lastUpdate);
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DAY_OF_YEAR, 30);
|
||||
Date nextUpdate = cal.getTime();
|
||||
crl.setNextUpdate(nextUpdate);
|
||||
|
||||
/* Add revoked certificate */
|
||||
byte[] serial = new byte[] { 0x01, 0x02, 0x03, 0x04 };
|
||||
Date revDate = new Date();
|
||||
crl.addRevoked(serial, revDate);
|
||||
|
||||
/* Sign CRL with ECC key */
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
|
||||
kpg.initialize(256);
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
PrivateKey privKey = keyPair.getPrivate();
|
||||
crl.sign(privKey, "SHA256");
|
||||
|
||||
/* Output to DER and PEM */
|
||||
byte[] derCrl = crl.getDer();
|
||||
byte[] pemCrl = crl.getPem();
|
||||
|
||||
assertNotNull(derCrl);
|
||||
assertTrue(derCrl.length > 0);
|
||||
assertNotNull(pemCrl);
|
||||
assertTrue(pemCrl.length > 0);
|
||||
|
||||
/* Free native memory */
|
||||
issuerName.free();
|
||||
crl.free();
|
||||
|
||||
System.out.println("\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFree()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\tfree()");
|
||||
|
||||
if (WolfSSL.isEnabledCRL() == 0) {
|
||||
/* CRL not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCRL crl = new WolfSSLCRL();
|
||||
assertNotNull(crl);
|
||||
|
||||
/* Free should work */
|
||||
crl.free();
|
||||
|
||||
/* Operations after free should throw IllegalStateException */
|
||||
try {
|
||||
crl.setVersion(1);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("setVersion after free should throw exception");
|
||||
} catch (IllegalStateException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
try {
|
||||
crl.getVersion();
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("getVersion after free should throw exception");
|
||||
} catch (IllegalStateException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Multiple free() calls should be safe */
|
||||
crl.free();
|
||||
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
}
|
||||
|
|
@ -39,6 +39,7 @@ import com.wolfssl.WolfSSLException;
|
|||
WolfSSLCertRequestTest.class,
|
||||
WolfSSLCertManagerTest.class,
|
||||
WolfSSLNameConstraintsTest.class
|
||||
WolfSSLCRLTest.class
|
||||
})
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue