Merge pull request #146 from cconlon/csrGen
Certificate Signing Request (CSR) support (WolfSSLCertRequest)pull/148/head
commit
b9f858397c
|
@ -419,9 +419,10 @@ to run the ProviderTest:
|
|||
examples\provider\ProviderTest.bat
|
||||
```
|
||||
|
||||
Or to run the X509v3 certificate generation example:
|
||||
Or to run the X509v3 certificate or CSR generation example:
|
||||
|
||||
```
|
||||
examples\X509v3CertificateGeneration.bat
|
||||
examples\X509CertRequest.bat
|
||||
```
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSL.c" />
|
||||
<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_WolfSSLContext.c" />
|
||||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLSession.c" />
|
||||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLX509Name.c" />
|
||||
|
@ -54,6 +55,7 @@
|
|||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSL.h" />
|
||||
<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_WolfSSLContext.h" />
|
||||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLSession.h" />
|
||||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLX509Name.h" />
|
||||
|
@ -430,4 +432,4 @@ ant</Command>
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -33,6 +33,9 @@
|
|||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLCertManager.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLCertRequest.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\native\com_wolfssl_WolfSSLContext.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -71,6 +74,9 @@
|
|||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLCertManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLCertRequest.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\native\com_wolfssl_WolfSSLContext.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@ -84,4 +90,4 @@
|
|||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -63,6 +63,27 @@ This will write out generated certificates to the following directory:
|
|||
examples/certs/generated/
|
||||
```
|
||||
|
||||
## Certificate Signing Request (CSR) Generation Example
|
||||
|
||||
An example is included which will generate Certificate Signing Requests (CSR)
|
||||
using the wolfSSL JNI library `WolfSSLCertRequest` class.
|
||||
|
||||
**X509CertRequest.java** - CSR generation example
|
||||
|
||||
This example is compiled when the `ant examples` target is executed, and can
|
||||
be run afterwards with the provided bash script:
|
||||
|
||||
```
|
||||
$ cd <wolfssljni_root>
|
||||
$ ./examples/X509CertRequest.sh
|
||||
```
|
||||
|
||||
This will write out generated CSRs to the following directory:
|
||||
|
||||
```
|
||||
examples/certs/generated/
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
Please contact the wolfSSL support team at support@wolfssl.com with any
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
cd %~dp0\build >NUL 2>NUL
|
||||
SETLOCAL
|
||||
|
||||
:: Populate correct config for build
|
||||
call ..\WindowsConfig.bat
|
||||
|
||||
:: Set PATH to include DLL for native wolfSSL and wolfSSL JNI (native library)
|
||||
SET PATH="%WOLFSSLJNI_DLL_DIR%;%WOLFSSL_DLL_DIR%";%PATH%
|
||||
|
||||
java -cp ".;..\..\lib\wolfssl.jar;..\..\lib\wolfssl-jsse.jar" -Djava.library.path="%WOLFSSLJNI_DLL_DIR%;%WOLFSSL_DLL_DIR%" X509CertRequest
|
||||
|
||||
ENDLOCAL
|
||||
cd %~dp0\..
|
|
@ -0,0 +1,366 @@
|
|||
/* X509CertRequest.java
|
||||
*
|
||||
* Copyright (C) 2006-2023 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
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import java.security.PublicKey;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import com.wolfssl.WolfSSL;
|
||||
import com.wolfssl.WolfSSLCertRequest;
|
||||
import com.wolfssl.WolfSSLX509Name;
|
||||
import com.wolfssl.WolfSSLException;
|
||||
import com.wolfssl.WolfSSLJNIException;
|
||||
|
||||
/**
|
||||
* Example application that demonstrates X509 Certificate Signing Request (CSR)
|
||||
* generation including various combinations.
|
||||
*
|
||||
* CSR using files as input for certs/keys
|
||||
* CSR using arrays as input for certs/keys
|
||||
* CSR using generated certs and keys
|
||||
*
|
||||
* Each sub-example is contained in a separate method.
|
||||
*
|
||||
* When run, generated certificates are written out to PEM and DER files,
|
||||
* with location specified by variables at the top of this class.
|
||||
*
|
||||
*/
|
||||
public class X509CertRequest {
|
||||
|
||||
private static String CERT_DIR = "../certs/";
|
||||
private static String GEN_DIR = CERT_DIR + "generated/";
|
||||
private static String CERT_DIR_FROM_ROOT = "./exammples/certs/generated/";
|
||||
|
||||
/* Existing certs/keys used for CSR gen example with files */
|
||||
private static String clientKeyDer = CERT_DIR + "client-key.der";
|
||||
private static String clientKeyPubDer = CERT_DIR + "client-keyPub.der";
|
||||
|
||||
/* Generated certificate signing request (CSR) locations. */
|
||||
private static String csrUsingFilesDer =
|
||||
GEN_DIR + "csr-using-files.der";
|
||||
private static String csrUsingFilesPem =
|
||||
GEN_DIR + "csr-using-files.pem";
|
||||
private static String csrUsingArraysDer =
|
||||
GEN_DIR + "csr-using-arrays.der";
|
||||
private static String csrUsingArraysPem =
|
||||
GEN_DIR + "csr-using-arrays.pem";
|
||||
private static String csrUsingGeneratedKeysDer =
|
||||
GEN_DIR + "csr-generated-keys.der";
|
||||
private static String csrUsingGeneratedKeysPem =
|
||||
GEN_DIR + "csr-generated-keys.pem";
|
||||
|
||||
/* Example Extension values */
|
||||
private static String test_KEY_USAGE =
|
||||
"digitalSignature,keyEncipherment,dataEncipherment";
|
||||
private static String test_EXT_KEY_USAGE =
|
||||
"clientAuth,serverAuth";
|
||||
private static String test_ALT_NAME =
|
||||
"alt.example.com";
|
||||
|
||||
/* Example Attribute values */
|
||||
private static String test_CHALLENGE_PASSWORD =
|
||||
"12345!@#$%";
|
||||
|
||||
private void writeFile(String path, byte[] bytes)
|
||||
throws IOException {
|
||||
|
||||
File genDir = new File(GEN_DIR);
|
||||
if (!genDir.exists()) {
|
||||
genDir.mkdir();
|
||||
}
|
||||
Files.write(new File(path).toPath(), bytes);
|
||||
}
|
||||
|
||||
private WolfSSLX509Name generateTestSubjectName()
|
||||
throws WolfSSLException {
|
||||
|
||||
WolfSSLX509Name subjectName = new WolfSSLX509Name();
|
||||
subjectName.setCountryName("US");
|
||||
subjectName.setStateOrProvinceName("Montana");
|
||||
subjectName.setStreetAddress("12345 Test Address");
|
||||
subjectName.setLocalityName("Bozeman");
|
||||
subjectName.setSurname("Test Surname");
|
||||
subjectName.setCommonName("example.com");
|
||||
subjectName.setEmailAddress("support@example.com");
|
||||
subjectName.setOrganizationName("wolfSSL Inc.");
|
||||
subjectName.setOrganizationalUnitName("Test and Development");
|
||||
subjectName.setPostalCode("59715");
|
||||
subjectName.setUserId("TestUserID");
|
||||
|
||||
return subjectName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate example Certificate Signing Request (CSR) using the following
|
||||
* files as input to the CSR generation process:
|
||||
*
|
||||
* clientKeyPubDer - Existing client public key in DER format
|
||||
* clientKeyDer - Existing client private key in DER format
|
||||
*
|
||||
* Generates and writes CSR out to the following paths in
|
||||
* both PEM and DER format (see variable values above):
|
||||
* csrUsingFilesDer (DER format)
|
||||
* csrUsingFilesPem (PEM format)
|
||||
*
|
||||
* @throws WolfSSLException if error occurs during CSR generation process.
|
||||
* @throws WolfSSLJNIException if native JNI error occurs
|
||||
* @throws IOException on error writing to output file locations
|
||||
*/
|
||||
public void generateCSRUsingFiles()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\nGenerating CSR using files");
|
||||
|
||||
/* Create new CSR object */
|
||||
WolfSSLCertRequest req = new WolfSSLCertRequest();
|
||||
|
||||
/* Set Subject Name */
|
||||
WolfSSLX509Name subjectName = generateTestSubjectName();
|
||||
req.setSubjectName(subjectName);
|
||||
|
||||
/* Set Public Key from existing public key DER file */
|
||||
req.setPublicKey(clientKeyPubDer, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
|
||||
/* Add Attributes */
|
||||
req.addAttribute(WolfSSL.NID_pkcs9_challengePassword,
|
||||
test_CHALLENGE_PASSWORD.getBytes());
|
||||
|
||||
/* Add Extensions */
|
||||
req.addExtension(WolfSSL.NID_key_usage, test_KEY_USAGE, false);
|
||||
req.addExtension(WolfSSL.NID_ext_key_usage, test_EXT_KEY_USAGE, false);
|
||||
req.addExtension(WolfSSL.NID_subject_alt_name, test_ALT_NAME, false);
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, true, true);
|
||||
|
||||
/* Sign CSR, using existing client key DER */
|
||||
req.signRequest(clientKeyDer, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1, "SHA256");
|
||||
|
||||
/* Output to DER and PEM files */
|
||||
byte[] derCsr = req.getDer();
|
||||
byte[] pemCsr = req.getPem();
|
||||
|
||||
/* Write out generated CSRs to files */
|
||||
writeFile(csrUsingFilesDer, derCsr);
|
||||
writeFile(csrUsingFilesPem, pemCsr);
|
||||
|
||||
System.out.println("... ");
|
||||
System.out.println(" " + CERT_DIR_FROM_ROOT +
|
||||
Paths.get(csrUsingFilesDer).getFileName());
|
||||
System.out.println(" " + CERT_DIR_FROM_ROOT +
|
||||
Paths.get(csrUsingFilesPem).getFileName());
|
||||
|
||||
/* Free native memory */
|
||||
subjectName.free();
|
||||
req.free();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate example Certificate Signing Request (CSR) using the following
|
||||
* files in array format as input to the CSR generation process:
|
||||
*
|
||||
* clientKeyPubDer - Existing client public key in DER format
|
||||
* clientKeyDer - Existing client private key in DER format
|
||||
*
|
||||
* Generates and writes CSR out to the following paths in
|
||||
* both PEM and DER format (see variable values above):
|
||||
* csrUsingArraysDer (DER format)
|
||||
* csrUsingArraysPem (PEM format)
|
||||
*
|
||||
* @throws WolfSSLException if error occurs during CSR generation process.
|
||||
* @throws WolfSSLJNIException if native JNI error occurs
|
||||
* @throws IOException on error writing to output file locations
|
||||
*/
|
||||
public void generateCSRUsingArrays()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\nGenerating CSR using arrays");
|
||||
|
||||
/* Create new CSR object */
|
||||
WolfSSLCertRequest req = new WolfSSLCertRequest();
|
||||
|
||||
/* Set Subject Name */
|
||||
WolfSSLX509Name subjectName = generateTestSubjectName();
|
||||
req.setSubjectName(subjectName);
|
||||
|
||||
/* Set Public Key from existing public key DER file */
|
||||
byte[] pubKey = Files.readAllBytes(Paths.get(clientKeyPubDer));
|
||||
req.setPublicKey(pubKey, WolfSSL.RSAk, WolfSSL.SSL_FILETYPE_ASN1);
|
||||
|
||||
/* Add Attributes */
|
||||
req.addAttribute(WolfSSL.NID_pkcs9_challengePassword,
|
||||
test_CHALLENGE_PASSWORD.getBytes());
|
||||
|
||||
/* Add Extensions */
|
||||
req.addExtension(WolfSSL.NID_key_usage, test_KEY_USAGE, false);
|
||||
req.addExtension(WolfSSL.NID_ext_key_usage, test_EXT_KEY_USAGE, false);
|
||||
req.addExtension(WolfSSL.NID_subject_alt_name, test_ALT_NAME, false);
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, true, true);
|
||||
|
||||
/* Sign CSR, using existing client key DER */
|
||||
byte[] privKey = Files.readAllBytes(Paths.get(clientKeyDer));
|
||||
req.signRequest(privKey, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1, "SHA256");
|
||||
|
||||
/* Output to DER and PEM files */
|
||||
byte[] derCsr = req.getDer();
|
||||
byte[] pemCsr = req.getPem();
|
||||
|
||||
/* Write out generated CSRs to files */
|
||||
writeFile(csrUsingArraysDer, derCsr);
|
||||
writeFile(csrUsingArraysPem, pemCsr);
|
||||
|
||||
System.out.println("... ");
|
||||
System.out.println(" " + CERT_DIR_FROM_ROOT +
|
||||
Paths.get(csrUsingArraysDer).getFileName());
|
||||
System.out.println(" " + CERT_DIR_FROM_ROOT +
|
||||
Paths.get(csrUsingArraysPem).getFileName());
|
||||
|
||||
/* Free native memory */
|
||||
subjectName.free();
|
||||
req.free();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate example Certificate Signing Request (CSR) using generated keys
|
||||
* for the CSR public and private signgin key, to be used in the CSR
|
||||
* generation process.
|
||||
*
|
||||
* Generates and writes CSR out to the following paths in
|
||||
* both PEM and DER format (see variable values above):
|
||||
* csrUsingGeneratedKeysDer (DER format)
|
||||
* csrUsingGeneratedKeysPem (PEM format)
|
||||
*
|
||||
* @throws WolfSSLException if error occurs during CSR generation process.
|
||||
* @throws WolfSSLJNIException if native JNI error occurs
|
||||
* @throws IOException on error writing to output file locations
|
||||
*/
|
||||
public void generateCSRUsingGeneratedKeys()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
|
||||
System.out.print("\nGenerating CSR with generated keys");
|
||||
|
||||
/* Create new CSR object */
|
||||
WolfSSLCertRequest req = new WolfSSLCertRequest();
|
||||
|
||||
/* Set Subject Name */
|
||||
WolfSSLX509Name subjectName = generateTestSubjectName();
|
||||
req.setSubjectName(subjectName);
|
||||
|
||||
/* Set Public Key from generated java.security.PublicKey */
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
|
||||
kpg.initialize(2048);
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
PublicKey pubKey = keyPair.getPublic();
|
||||
req.setPublicKey(pubKey);
|
||||
|
||||
/* Add Attributes */
|
||||
req.addAttribute(WolfSSL.NID_pkcs9_challengePassword,
|
||||
test_CHALLENGE_PASSWORD.getBytes());
|
||||
|
||||
/* Add Extensions */
|
||||
req.addExtension(WolfSSL.NID_key_usage, test_KEY_USAGE, false);
|
||||
req.addExtension(WolfSSL.NID_ext_key_usage, test_EXT_KEY_USAGE, false);
|
||||
req.addExtension(WolfSSL.NID_subject_alt_name, test_ALT_NAME, false);
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, true, true);
|
||||
|
||||
/* Sign CSR, with java.security.PrivateKey */
|
||||
PrivateKey privKey = keyPair.getPrivate();
|
||||
req.signRequest(privKey, "SHA256");
|
||||
|
||||
/* Output to DER and PEM files */
|
||||
byte[] derCsr = req.getDer();
|
||||
byte[] pemCsr = req.getPem();
|
||||
|
||||
/* Write out generated CSRs to files */
|
||||
writeFile(csrUsingGeneratedKeysDer, derCsr);
|
||||
writeFile(csrUsingGeneratedKeysPem, pemCsr);
|
||||
|
||||
System.out.println("... ");
|
||||
System.out.println(" " + CERT_DIR_FROM_ROOT +
|
||||
Paths.get(csrUsingGeneratedKeysDer).getFileName());
|
||||
System.out.println(" " + CERT_DIR_FROM_ROOT +
|
||||
Paths.get(csrUsingGeneratedKeysPem).getFileName());
|
||||
|
||||
/* Free native memory */
|
||||
subjectName.free();
|
||||
req.free();
|
||||
}
|
||||
|
||||
public void run(String[] args) {
|
||||
|
||||
int ret = 0;
|
||||
|
||||
try {
|
||||
/* Initialize and load native wolfSSL library, enable debugging */
|
||||
WolfSSL.loadLibrary();
|
||||
WolfSSL sslLib = new WolfSSL();
|
||||
|
||||
/* Enable debugging if desired */
|
||||
//sslLib.debuggingON();
|
||||
|
||||
System.out.println(
|
||||
"wolfSSL JNI Certificate Signing Request Generation Example");
|
||||
|
||||
if (!WolfSSL.certReqEnabled()) {
|
||||
System.out.println("ERROR: Native wolfSSL must be compiled " +
|
||||
"with --enable-certreq or WOLFSSL_CERT_REQ to use this " +
|
||||
"example");
|
||||
|
||||
/* exit with error */
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
/* Generate example Certificate Signing Request files */
|
||||
generateCSRUsingFiles();
|
||||
generateCSRUsingArrays();
|
||||
generateCSRUsingGeneratedKeys();
|
||||
|
||||
} catch (WolfSSLException | WolfSSLJNIException |
|
||||
IOException | CertificateException |
|
||||
NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
/* exit with error */
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
} /* end run() */
|
||||
|
||||
public static void main(String[] args) {
|
||||
new X509CertRequest().run(args);
|
||||
}
|
||||
|
||||
} /* end X509CertRequest */
|
||||
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Allow user to override which openssl binary is used to verify certs
|
||||
if [ -z "${OPENSSL}" ]; then
|
||||
OPENSSL=openssl
|
||||
fi
|
||||
|
||||
cd ./examples/build
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../lib/:/usr/local/lib
|
||||
java -classpath ../../lib/wolfssl.jar:./ -Dsun.boot.library.path=../../lib/ -Xcheck:jni X509CertRequest $@
|
||||
|
||||
if [ $? != 0 ]; then
|
||||
printf "\nExample failed\n"
|
||||
exit -1
|
||||
else
|
||||
printf "\nExample passed\n"
|
||||
fi
|
||||
|
||||
which $OPENSSL > /dev/null
|
||||
if [ $? != 0 ]; then
|
||||
printf "openssl not detected, skipping cert verification\n"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
printf "\nVerifying CSRs with openssl...\n"
|
||||
|
||||
printf "Testing each can be opened with openssl req -text\n"
|
||||
|
||||
# Test reading each DER CSR
|
||||
CERT_FILES="../certs/generated/csr*.der"
|
||||
for f in $CERT_FILES
|
||||
do
|
||||
$OPENSSL req -inform DER -in $f -text -noout > /dev/null
|
||||
if [ $? != 0 ]; then
|
||||
printf "File not readable with openssl req: $f\n"
|
||||
exit -1
|
||||
fi
|
||||
done
|
||||
|
||||
# Test reading each PEM CSR
|
||||
CERT_FILES="../certs/generated/csr*.pem"
|
||||
for f in $CERT_FILES
|
||||
do
|
||||
$OPENSSL req -inform PEM -in $f -text -noout > /dev/null
|
||||
if [ $? != 0 ]; then
|
||||
printf "File not readable with openssl req: $f\n"
|
||||
exit -1
|
||||
fi
|
||||
done
|
||||
|
||||
printf "Verification successful\n"
|
Binary file not shown.
|
@ -41,6 +41,7 @@ certList=(
|
|||
"client-key.der"
|
||||
"client-keyPub.der"
|
||||
"dh2048.pem"
|
||||
"ecc-client-key.der"
|
||||
"ecc-client-key.pem"
|
||||
"ecc-key.pem"
|
||||
"server-cert.pem"
|
||||
|
|
3
java.sh
3
java.sh
|
@ -115,10 +115,11 @@ gcc -Wall -c $fpic $cflags ./native/com_wolfssl_wolfcrypt_RSA.c -o ./native/com_
|
|||
gcc -Wall -c $fpic $cflags ./native/com_wolfssl_wolfcrypt_ECC.c -o ./native/com_wolfssl_wolfcrypt_ECC.o $javaIncludes
|
||||
gcc -Wall -c $fpic $cflags ./native/com_wolfssl_wolfcrypt_EccKey.c -o ./native/com_wolfssl_wolfcrypt_EccKey.o $javaIncludes
|
||||
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_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 $javaLibs $cflags -o ./lib/$jniLibName ./native/com_wolfssl_WolfSSL.o ./native/com_wolfssl_WolfSSLSession.o ./native/com_wolfssl_WolfSSLContext.o ./native/com_wolfssl_wolfcrypt_RSA.o ./native/com_wolfssl_wolfcrypt_ECC.o ./native/com_wolfssl_wolfcrypt_EccKey.o ./native/com_wolfssl_WolfSSLCertManager.o ./native/com_wolfssl_WolfSSLCertificate.o ./native/com_wolfssl_WolfSSLX509Name.o ./native/com_wolfssl_WolfSSLX509StoreCtx.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_wolfcrypt_RSA.o ./native/com_wolfssl_wolfcrypt_ECC.o ./native/com_wolfssl_wolfcrypt_EccKey.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 -L$WOLFSSL_INSTALL_DIR/lib -L$WOLFSSL_INSTALL_DIR/lib64 -l$WOLFSSL_LIBNAME
|
||||
if [ $? != 0 ]; then
|
||||
echo "Error creating native JNI library"
|
||||
exit 1
|
||||
|
|
|
@ -386,6 +386,19 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_FileSystemEnabled
|
|||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_certReqEnabled
|
||||
(JNIEnv* jenv, jclass jcl)
|
||||
{
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
|
||||
#ifdef WOLFSSL_CERT_REQ
|
||||
return JNI_TRUE;
|
||||
#else
|
||||
return JNI_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSL_SSLv3_1ServerMethod
|
||||
(JNIEnv* jenv, jclass jcl)
|
||||
{
|
||||
|
|
|
@ -211,6 +211,20 @@ extern "C" {
|
|||
#define com_wolfssl_WolfSSL_ASN_URI_TYPE 6L
|
||||
#undef com_wolfssl_WolfSSL_ASN_IP_TYPE
|
||||
#define com_wolfssl_WolfSSL_ASN_IP_TYPE 7L
|
||||
#undef com_wolfssl_WolfSSL_NID_surname
|
||||
#define com_wolfssl_WolfSSL_NID_surname 4L
|
||||
#undef com_wolfssl_WolfSSL_NID_serialNumber
|
||||
#define com_wolfssl_WolfSSL_NID_serialNumber 5L
|
||||
#undef com_wolfssl_WolfSSL_NID_pkcs9_unstructuredName
|
||||
#define com_wolfssl_WolfSSL_NID_pkcs9_unstructuredName 49L
|
||||
#undef com_wolfssl_WolfSSL_NID_pkcs9_contentType
|
||||
#define com_wolfssl_WolfSSL_NID_pkcs9_contentType 50L
|
||||
#undef com_wolfssl_WolfSSL_NID_pkcs9_challengePassword
|
||||
#define com_wolfssl_WolfSSL_NID_pkcs9_challengePassword 54L
|
||||
#undef com_wolfssl_WolfSSL_NID_givenName
|
||||
#define com_wolfssl_WolfSSL_NID_givenName 100L
|
||||
#undef com_wolfssl_WolfSSL_NID_initials
|
||||
#define com_wolfssl_WolfSSL_NID_initials 101L
|
||||
#undef com_wolfssl_WolfSSL_NID_key_usage
|
||||
#define com_wolfssl_WolfSSL_NID_key_usage 129L
|
||||
#undef com_wolfssl_WolfSSL_NID_subject_alt_name
|
||||
|
@ -219,6 +233,8 @@ extern "C" {
|
|||
#define com_wolfssl_WolfSSL_NID_basic_constraints 133L
|
||||
#undef com_wolfssl_WolfSSL_NID_ext_key_usage
|
||||
#define com_wolfssl_WolfSSL_NID_ext_key_usage 151L
|
||||
#undef com_wolfssl_WolfSSL_NID_dnQualifier
|
||||
#define com_wolfssl_WolfSSL_NID_dnQualifier 174L
|
||||
#undef com_wolfssl_WolfSSL_WOLFSSL_NAMED_GROUP_INVALID
|
||||
#define com_wolfssl_WolfSSL_WOLFSSL_NAMED_GROUP_INVALID 0L
|
||||
#undef com_wolfssl_WolfSSL_WOLFSSL_ECC_SECT163K1
|
||||
|
@ -477,6 +493,14 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_RsaEnabled
|
|||
JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_FileSystemEnabled
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSL
|
||||
* Method: certReqEnabled
|
||||
* Signature: ()Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_certReqEnabled
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSL
|
||||
* Method: SSLv3_ServerMethod
|
||||
|
|
|
@ -0,0 +1,728 @@
|
|||
/* com_wolfssl_WolfSSLCertRequest.c
|
||||
*
|
||||
* Copyright (C) 2006-2023 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/wolfcrypt/asn_public.h>
|
||||
#include <wolfssl/openssl/evp.h> /* for EVP_PKEY functions */
|
||||
#include <wolfssl/openssl/x509v3.h> /* for WOLFSSL_X509_EXTENSION */
|
||||
#include <wolfssl/error-ssl.h>
|
||||
|
||||
#include "com_wolfssl_globals.h"
|
||||
#include "com_wolfssl_WolfSSLCertRequest.h"
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1new
|
||||
(JNIEnv* jenv, jclass jcl)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_ALL) && \
|
||||
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
|
||||
WOLFSSL_X509* x509 = NULL;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL) {
|
||||
return (jlong)0;
|
||||
}
|
||||
|
||||
x509 = wolfSSL_X509_REQ_new();
|
||||
if (x509 == NULL) {
|
||||
return (jlong)0;
|
||||
}
|
||||
|
||||
return (jlong)(uintptr_t)x509;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
return (jlong)0;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1free
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_ALL) && \
|
||||
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509ReqPtr;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || x509 == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
wolfSSL_X509_REQ_free(x509);
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1set_1subject_1name
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr, jlong x509NamePtr)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_ALL) && \
|
||||
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509ReqPtr;
|
||||
WOLFSSL_X509_NAME* x509Name = (WOLFSSL_X509_NAME*)(uintptr_t)x509NamePtr;
|
||||
int ret = WOLFSSL_FAILURE;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || x509 == NULL || x509Name == NULL) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wolfSSL_X509_REQ_set_subject_name(x509, x509Name);
|
||||
|
||||
return ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)x509ReqPtr;
|
||||
(void)x509NamePtr;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1add1_1attr_1by_1NID
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr, jint nid, jint type, jbyteArray attrBytes)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_ALL) && \
|
||||
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509ReqPtr;
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
unsigned char* attr = NULL;
|
||||
int attrSz = 0;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || x509 == NULL || attrBytes == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
attr = (byte*)(*jenv)->GetByteArrayElements(jenv, attrBytes, NULL);
|
||||
attrSz = (*jenv)->GetArrayLength(jenv, attrBytes);
|
||||
|
||||
if (attr == NULL || attrSz <= 0) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
ret = X509_REQ_add1_attr_by_NID(x509, (int)nid, (int)type,
|
||||
attr, attrSz);
|
||||
}
|
||||
|
||||
(*jenv)->ReleaseByteArrayElements(jenv, attrBytes, (jbyte*)attr, JNI_ABORT);
|
||||
|
||||
return (jint)ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)x509ReqPtr;
|
||||
(void)nid;
|
||||
(void)type;
|
||||
(void)attrBytes;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1set_1version
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr, jlong version)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
|
||||
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509ReqPtr;
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || x509 == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
ret = X509_REQ_set_version(x509, (long)version);
|
||||
|
||||
return (jint)ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)x509ReqPtr;
|
||||
(void)version;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1print
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
|
||||
defined(OPENSSL_EXTRA) && !defined(NO_BIO) && defined(XSNPRINTF) && \
|
||||
defined(WOLFSSL_CERT_REQ)
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509ReqPtr;
|
||||
WOLFSSL_BIO* bio = NULL;
|
||||
char* mem = NULL;
|
||||
int sz = 0;
|
||||
jbyteArray memArr = NULL;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || x509 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem());
|
||||
if (bio == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (wolfSSL_X509_REQ_print(bio, x509) != 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)) {
|
||||
/* failed to set byte region */
|
||||
(*jenv)->DeleteLocalRef(jenv, memArr);
|
||||
wolfSSL_BIO_free(bio);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
wolfSSL_BIO_free(bio);
|
||||
return memArr;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)x509ReqPtr;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1sign
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr, jint keyType, jbyteArray keyBytes, jint fileFormat, jstring digestAlg)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_ALL) && \
|
||||
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ)
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509ReqPtr;
|
||||
byte* keyBuf = NULL;
|
||||
byte* derBuf = NULL;
|
||||
int keySz = 0;
|
||||
int derSz = 0;
|
||||
byte derAllocated = 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 || x509 == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
keyBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, keyBytes, NULL);
|
||||
keySz = (*jenv)->GetArrayLength(jenv, keyBytes);
|
||||
|
||||
if (keyBuf == NULL || keySz == 0) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
/* Set correct WOLFSSL_EVP_MD, does not need to be freed */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
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)fileFormat == 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 {
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
derAllocated = 1;
|
||||
XMEMSET(derBuf, 0, derSz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* convert PEM to DER if derBuf has been allocated */
|
||||
if (derAllocated == 1 && ret == WOLFSSL_SUCCESS) {
|
||||
ret = wc_KeyPemToDer(keyBuf, keySz, derBuf, derSz, NULL);
|
||||
if (ret <= 0 || ret != derSz) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* convert buffer into WOLFSSL_EVP_PKEY */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
rsaPrivBuf = derBuf;
|
||||
|
||||
priv = wolfSSL_d2i_PrivateKey((int)keyType, NULL,
|
||||
(const unsigned char**)&rsaPrivBuf, derSz);
|
||||
if (priv == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* sign WOLFSSL_X509 with WOLFSSL_EVP_PKEY, returns size of signature
|
||||
* on success or negative on error */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_X509_REQ_sign(x509, priv, md);
|
||||
if (ret >= 0) {
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (priv != NULL) {
|
||||
wolfSSL_EVP_PKEY_free(priv);
|
||||
}
|
||||
if (derAllocated == 1 && derBuf != NULL) {
|
||||
XMEMSET(derBuf, 0, derSz);
|
||||
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
(*jenv)->ReleaseByteArrayElements(jenv, keyBytes, (jbyte*)keyBuf,
|
||||
JNI_ABORT);
|
||||
(*jenv)->ReleaseStringUTFChars(jenv, digestAlg, mdName);
|
||||
|
||||
return (jint)ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)x509ReqPtr;
|
||||
(void)keyType;
|
||||
(void)keyBytes;
|
||||
(void)fileFormat;
|
||||
(void)digestAlg;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1set_1pubkey_1native_1open
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr, jint keyType, jbyteArray fileBytes, jint fileFormat)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
|
||||
(defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509ReqPtr;
|
||||
byte* fileBuf = NULL;
|
||||
byte* derBuf = NULL;
|
||||
int fileSz = 0;
|
||||
int derSz = 0;
|
||||
byte derAllocated = 0;
|
||||
WOLFSSL_EVP_PKEY* pub = NULL;
|
||||
unsigned char* rsaPubBuf = NULL;
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || x509 == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
fileBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, fileBytes, NULL);
|
||||
fileSz = (*jenv)->GetArrayLength(jenv, fileBytes);
|
||||
|
||||
if (fileBuf == NULL || fileSz == 0) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
/* convert PEM to DER if needed */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if ((int)fileFormat == WOLFSSL_FILETYPE_ASN1) {
|
||||
/* already in DER */
|
||||
derBuf = fileBuf;
|
||||
derSz = fileSz;
|
||||
}
|
||||
else {
|
||||
/* get needed buffer size */
|
||||
ret = wc_KeyPemToDer(fileBuf, fileSz, 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 {
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
derAllocated = 1;
|
||||
XMEMSET(derBuf, 0, derSz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* convert PEM to DER if derBuf has been allocated */
|
||||
if (derAllocated == 1 && ret == WOLFSSL_SUCCESS) {
|
||||
ret = wc_KeyPemToDer(fileBuf, fileSz, derBuf, derSz, NULL);
|
||||
if (ret <= 0 || ret != derSz) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
ret = WOLFSSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* convert buffer into WOLFSSL_EVP_PKEY */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
rsaPubBuf = derBuf;
|
||||
|
||||
pub = wolfSSL_d2i_PUBKEY(NULL, (const unsigned char**)&rsaPubBuf, derSz);
|
||||
if (pub == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/* set WOLFSSL_EVP_PKEY into WOLFSSL_X509 */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_X509_set_pubkey(x509, pub);
|
||||
}
|
||||
|
||||
if (pub != NULL) {
|
||||
/* free WOLFSSL_EVP_PKEY, since X509_set_pubkey() makes copy */
|
||||
wolfSSL_EVP_PKEY_free(pub);
|
||||
}
|
||||
if (derAllocated == 1 && derBuf != NULL) {
|
||||
XMEMSET(derBuf, 0, derSz);
|
||||
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
(*jenv)->ReleaseByteArrayElements(jenv, fileBytes, (jbyte*)fileBuf,
|
||||
JNI_ABORT);
|
||||
|
||||
return (jint)ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)x509ReqPtr;
|
||||
(void)keyType;
|
||||
(void)fileBytes;
|
||||
(void)fileFormat;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1get_1der
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_ALL) && \
|
||||
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
|
||||
!defined(NO_BIO)
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509ReqPtr;
|
||||
unsigned char* der = NULL;
|
||||
jbyteArray derArr = NULL;
|
||||
jclass excClass = NULL;
|
||||
int sz = 0;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || x509 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sz = wolfSSL_i2d_X509_REQ(x509, &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_REQ_get_der");
|
||||
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_REQ_get_der");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
|
||||
return derArr;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)x509ReqPtr;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1get_1pem
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_ALL) && \
|
||||
defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) && \
|
||||
!defined(NO_BIO)
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509ReqPtr;
|
||||
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 || x509 == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sz = wolfSSL_i2d_X509_REQ(x509, &der);
|
||||
if (sz <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pemSz = wc_DerToPem(der, sz, NULL, 0, CERTREQ_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, CERTREQ_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_REQ_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_get_pem");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
return pemArr;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)x509ReqPtr;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1add_1ext_1via_1nconf_1nid
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr, jint nid, jstring extValue, jboolean isCritical)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509ReqPtr;
|
||||
WOLFSSL_X509_EXTENSION* ext = NULL;
|
||||
const char* value = NULL;
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || x509 == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
value = (*jenv)->GetStringUTFChars(jenv, extValue, 0);
|
||||
if (value == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
ext = wolfSSL_X509V3_EXT_nconf_nid(NULL, NULL, (int)nid, value);
|
||||
if (ext == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (isCritical == JNI_TRUE) {
|
||||
ret = wolfSSL_X509_EXTENSION_set_critical(ext, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_X509_add_ext(x509, ext, -1);
|
||||
}
|
||||
|
||||
if (ext != NULL) {
|
||||
wolfSSL_X509_EXTENSION_free(ext);
|
||||
}
|
||||
|
||||
(*jenv)->ReleaseStringUTFChars(jenv, extValue, value);
|
||||
|
||||
return (jint)ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)x509ReqPtr;
|
||||
(void)nid;
|
||||
(void)extValue;
|
||||
(void)isCritical;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1add_1ext_1via_1set_1object_1boolean
|
||||
(JNIEnv* jenv, jclass jcl, jlong x509ReqPtr, jint nid, jboolean extValue, jboolean isCritical)
|
||||
{
|
||||
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
|
||||
WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509ReqPtr;
|
||||
WOLFSSL_X509_EXTENSION* ext = NULL;
|
||||
WOLFSSL_ASN1_OBJECT* obj = NULL;
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || x509 == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
ext = wolfSSL_X509_EXTENSION_new();
|
||||
if (ext == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (isCritical == JNI_TRUE) {
|
||||
ret = wolfSSL_X509_EXTENSION_set_critical(ext, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
obj = wolfSSL_OBJ_nid2obj((int)nid);
|
||||
if (obj == NULL) {
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (extValue == JNI_TRUE) {
|
||||
obj->ca = 1;
|
||||
}
|
||||
else {
|
||||
obj->ca = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_X509_EXTENSION_set_object(ext, obj);
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
ret = wolfSSL_X509_add_ext(x509, ext, -1);
|
||||
}
|
||||
|
||||
|
||||
if (obj != NULL) {
|
||||
wolfSSL_ASN1_OBJECT_free(obj);
|
||||
}
|
||||
if (ext != NULL) {
|
||||
wolfSSL_X509_EXTENSION_free(ext);
|
||||
}
|
||||
|
||||
return (jint)ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)x509ReqPtr;
|
||||
(void)nid;
|
||||
(void)extValue;
|
||||
(void)isCritical;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* Header for class com_wolfssl_WolfSSLCertRequest */
|
||||
|
||||
#ifndef _Included_com_wolfssl_WolfSSLCertRequest
|
||||
#define _Included_com_wolfssl_WolfSSLCertRequest
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#undef com_wolfssl_WolfSSLCertRequest_EVP_PKEY_RSA
|
||||
#define com_wolfssl_WolfSSLCertRequest_EVP_PKEY_RSA 16L
|
||||
#undef com_wolfssl_WolfSSLCertRequest_EVP_PKEY_EC
|
||||
#define com_wolfssl_WolfSSLCertRequest_EVP_PKEY_EC 18L
|
||||
#undef com_wolfssl_WolfSSLCertRequest_MBSTRING_ASC
|
||||
#define com_wolfssl_WolfSSLCertRequest_MBSTRING_ASC 4097L
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_REQ_new
|
||||
* Signature: ()J
|
||||
*/
|
||||
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1new
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_REQ_free
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1free
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_REQ_set_subject_name
|
||||
* Signature: (JJ)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1set_1subject_1name
|
||||
(JNIEnv *, jclass, jlong, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_REQ_add1_attr_by_NID
|
||||
* Signature: (JII[B)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1add1_1attr_1by_1NID
|
||||
(JNIEnv *, jclass, jlong, jint, jint, jbyteArray);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_REQ_set_version
|
||||
* Signature: (JJ)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1set_1version
|
||||
(JNIEnv *, jclass, jlong, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_REQ_print
|
||||
* Signature: (J)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1print
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_REQ_sign
|
||||
* Signature: (JI[BILjava/lang/String;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1sign
|
||||
(JNIEnv *, jclass, jlong, jint, jbyteArray, jint, jstring);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_REQ_set_pubkey_native_open
|
||||
* Signature: (JI[BI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1set_1pubkey_1native_1open
|
||||
(JNIEnv *, jclass, jlong, jint, jbyteArray, jint);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_REQ_get_der
|
||||
* Signature: (J)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1get_1der
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_REQ_get_pem
|
||||
* Signature: (J)[B
|
||||
*/
|
||||
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1REQ_1get_1pem
|
||||
(JNIEnv *, jclass, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_add_ext_via_nconf_nid
|
||||
* Signature: (JILjava/lang/String;Z)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1add_1ext_1via_1nconf_1nid
|
||||
(JNIEnv *, jclass, jlong, jint, jstring, jboolean);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLCertRequest
|
||||
* Method: X509_add_ext_via_set_object_boolean
|
||||
* Signature: (JIZZ)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertRequest_X509_1add_1ext_1via_1set_1object_1boolean
|
||||
(JNIEnv *, jclass, jlong, jint, jboolean, jboolean);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -361,14 +361,30 @@ public class WolfSSL {
|
|||
public static final int ASN_IP_TYPE = 0x07;
|
||||
|
||||
/* NIDs, from native asn.h */
|
||||
/** Surname NID */
|
||||
public static final int NID_surname = 4;
|
||||
/** Serial number NID */
|
||||
public static final int NID_serialNumber = 5;
|
||||
/** PKCS9 Unstructured name NID */
|
||||
public static final int NID_pkcs9_unstructuredName = 49;
|
||||
/** PKCS9 contentType NID */
|
||||
public static final int NID_pkcs9_contentType = 50;
|
||||
/** PKCS9 challenge password NID */
|
||||
public static final int NID_pkcs9_challengePassword = 54;
|
||||
/** Given name NID */
|
||||
public static final int NID_givenName = 100;
|
||||
/** Initials NID */
|
||||
public static final int NID_initials = 101;
|
||||
/** Key Usage NID */
|
||||
public static final int NID_key_usage = 129;
|
||||
public static final int NID_key_usage = 129;
|
||||
/** Subject Alternative Name NID */
|
||||
public static final int NID_subject_alt_name = 131;
|
||||
public static final int NID_subject_alt_name = 131;
|
||||
/** Basic Constraints NID */
|
||||
public static final int NID_basic_constraints = 133;
|
||||
public static final int NID_basic_constraints = 133;
|
||||
/** Extended Key Usage NID */
|
||||
public static final int NID_ext_key_usage = 151;
|
||||
public static final int NID_ext_key_usage = 151;
|
||||
/** Domain name qualifier NID */
|
||||
public static final int NID_dnQualifier = 174;
|
||||
|
||||
/* is this object active, or has it been cleaned up? */
|
||||
private boolean active = false;
|
||||
|
@ -590,52 +606,61 @@ public class WolfSSL {
|
|||
* TLS 1.0 is disabled by default in native wolfSSL, unless the user
|
||||
* has configured wolfSSL with "--enable-tls10".
|
||||
*
|
||||
* @return 1 if enabled, otherwise 0 if not compiled in.
|
||||
* @return true if enabled, otherwise false if not compiled in.
|
||||
*/
|
||||
public static native boolean TLSv1Enabled();
|
||||
|
||||
/**
|
||||
* Tests if TLS 1.1 has been compiled into the native wolfSSL library.
|
||||
*
|
||||
* @return 1 if enabled, otherwise 0 if not compiled in.
|
||||
* @return true if enabled, otherwise false if not compiled in.
|
||||
*/
|
||||
public static native boolean TLSv11Enabled();
|
||||
|
||||
/**
|
||||
* Tests if TLS 1.2 has been compiled into the native wolfSSL library.
|
||||
*
|
||||
* @return 1 if enabled, otherwise 0 if not compiled in.
|
||||
* @return true if enabled, otherwise false if not compiled in.
|
||||
*/
|
||||
public static native boolean TLSv12Enabled();
|
||||
|
||||
/**
|
||||
* Tests if TLS 1.3 has been compiled into the native wolfSSL library.
|
||||
*
|
||||
* @return 1 if enabled, otherwise 0 if not compiled in.
|
||||
* @return true if enabled, otherwise false if not compiled in.
|
||||
*/
|
||||
public static native boolean TLSv13Enabled();
|
||||
|
||||
/**
|
||||
* Tests if ECC support has been compiled into the native wolfSSL library.
|
||||
*
|
||||
* @return 1 if enabled, otherwise 0 if not compiled in.
|
||||
* @return true if enabled, otherwise false if not compiled in.
|
||||
*/
|
||||
public static native boolean EccEnabled();
|
||||
|
||||
/**
|
||||
* Tests if RSA support has been compiled into the native wolfSSL library.
|
||||
*
|
||||
* @return 1 if enabled, otherwise 0 if not compiled in.
|
||||
* @return true if enabled, otherwise false if not compiled in.
|
||||
*/
|
||||
public static native boolean RsaEnabled();
|
||||
|
||||
/**
|
||||
* Tests if filesystem support has been compiled into the wolfSSL library.
|
||||
*
|
||||
* @return 1 if enabled, otherwise 0 if NO_FILESYSTEM has been defined.
|
||||
* @return true if enabled, otherwise false if NO_FILESYSTEM has been
|
||||
* defined.
|
||||
*/
|
||||
public static native boolean FileSystemEnabled();
|
||||
|
||||
/**
|
||||
* Tests if Certificate Signing Request (CSR) support has been compiled
|
||||
* into the native wolfSSL library.
|
||||
*
|
||||
* @return true if enabled, otherwise false if WOLFSSL_CERT_EXT not defined.
|
||||
*/
|
||||
public static native boolean certReqEnabled();
|
||||
|
||||
/* ---------------- native SSL/TLS version functions ---------------- */
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,730 @@
|
|||
/* WolfSSLCertRequest.java
|
||||
*
|
||||
* Copyright (C) 2006-2023 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.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.PublicKey;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.interfaces.ECPrivateKey;
|
||||
|
||||
/**
|
||||
* WolfSSLCertRequest class, wraps native X509_REQ functionality.
|
||||
*/
|
||||
public class WolfSSLCertRequest {
|
||||
|
||||
private boolean active = false;
|
||||
|
||||
/* native X509_REQ pointer */
|
||||
private long x509ReqPtr = 0;
|
||||
|
||||
/* lock around active state */
|
||||
private final Object stateLock = new Object();
|
||||
|
||||
/* lock around native X509_REQ pointer use */
|
||||
private final Object x509ReqLock = new Object();
|
||||
|
||||
/* Public key types used for CSR, mirrored from
|
||||
* native enum in wolfssl/openssl/evp.h */
|
||||
private static final int EVP_PKEY_RSA = 16;
|
||||
private static final int EVP_PKEY_EC = 18;
|
||||
|
||||
/* Define from <wolfssl/openssl/asn1.h> */
|
||||
private static final int MBSTRING_ASC = 0x1001;
|
||||
|
||||
/* Native JNI methods */
|
||||
static native long X509_REQ_new();
|
||||
static native void X509_REQ_free(long x509ReqPtr);
|
||||
static native int X509_REQ_set_subject_name(long x509ReqPtr,
|
||||
long x509NamePtr);
|
||||
static native int X509_REQ_add1_attr_by_NID(long x509ReqPtr, int nid,
|
||||
int type, byte[] bytes);
|
||||
static native int X509_REQ_set_version(long x509ReqPtr, long ver);
|
||||
static native byte[] X509_REQ_print(long x509ReqPtr);
|
||||
static native int X509_REQ_sign(long x509ReqPtr, int evpKeyType,
|
||||
byte[] keyBytes, int format, String digestAlg);
|
||||
static native int X509_REQ_set_pubkey_native_open(long x509ReqPtr,
|
||||
int keyType, byte[] fileBytes, int format);
|
||||
static native byte[] X509_REQ_get_der(long x509);
|
||||
static native byte[] X509_REQ_get_pem(long x509);
|
||||
static native int X509_add_ext_via_nconf_nid(long x509Ptr, int nid,
|
||||
String extValue, boolean isCritical);
|
||||
static native int X509_add_ext_via_set_object_boolean(long x509Ptr,
|
||||
int nid, boolean extValue, boolean isCritical);
|
||||
|
||||
/**
|
||||
* Create new empty WolfSSLCertRequest object, for use with CSR generation
|
||||
*
|
||||
* @throws WolfSSLException if native API call fails.
|
||||
*/
|
||||
public WolfSSLCertRequest() throws WolfSSLException {
|
||||
|
||||
x509ReqPtr = X509_REQ_new();
|
||||
if (x509ReqPtr == 0) {
|
||||
throw new WolfSSLException("Failed to create WolfSSLCertRequest");
|
||||
}
|
||||
|
||||
synchronized (stateLock) {
|
||||
this.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the current WolfSSLCertRequest object is active.
|
||||
*
|
||||
* @throws IllegalStateException if object has been freed
|
||||
*/
|
||||
private void confirmObjectIsActive()
|
||||
throws IllegalStateException {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (this.active == false) {
|
||||
throw new IllegalStateException(
|
||||
"WolfSSLCertRequest object has been freed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Subject Name to be used with this WolfSSLCertRequest.
|
||||
* Note that the WolfSSLX509Name object should be completely set up
|
||||
* before calling this method. This method copies/duplicates the contents
|
||||
* of the WOLFSSL_X509_NAME (WolfSSLX509Name) into the native
|
||||
* WOLFSSL_X509 structure.
|
||||
*
|
||||
* @param name Initialized and populated WolfSSLX509 name to be set into
|
||||
* Subject Name of WolfSSLCertRequest for cert generation.
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws WolfSSLException if native JNI error occurs.
|
||||
*/
|
||||
public void setSubjectName(WolfSSLX509Name name)
|
||||
throws IllegalStateException, WolfSSLException {
|
||||
|
||||
int ret;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
/* TODO somehow lock WolfSSLX509Name object while using pointer? */
|
||||
ret = X509_REQ_set_subject_name(this.x509ReqPtr,
|
||||
name.getNativeX509NamePtr());
|
||||
}
|
||||
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new WolfSSLException("Error setting subject name " +
|
||||
"(ret: " + ret + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a CSR attribute to this WolfSSLCertRequest
|
||||
*
|
||||
* @param nid NID of an attribute to add. Must be one of:
|
||||
* WolfSSL.NID_pkcs9_challengePassword
|
||||
* WolfSSL.NID_serialNumber
|
||||
* WolfSSL.NID_pkcs9_unstructuredName
|
||||
* WolfSSL.NID_pkcs9_contentType
|
||||
* WolfSSL.NID_surname
|
||||
* WolfSSL.NID_initials
|
||||
* WolfSSL.NID_givenName
|
||||
* WolfSSL.NID_dnQualifier
|
||||
* @param value value of attribute to set, if passing in String, use
|
||||
* String.getBytes()
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws WolfSSLException if native JNI error occurs.
|
||||
*/
|
||||
public void addAttribute(int nid, byte[] value)
|
||||
throws IllegalStateException, WolfSSLException {
|
||||
|
||||
int ret;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
if (nid != WolfSSL.NID_pkcs9_challengePassword &&
|
||||
nid != WolfSSL.NID_serialNumber &&
|
||||
nid != WolfSSL.NID_pkcs9_unstructuredName &&
|
||||
nid != WolfSSL.NID_pkcs9_contentType &&
|
||||
nid != WolfSSL.NID_surname &&
|
||||
nid != WolfSSL.NID_initials &&
|
||||
nid != WolfSSL.NID_givenName &&
|
||||
nid != WolfSSL.NID_dnQualifier) {
|
||||
throw new WolfSSLException(
|
||||
"Unsupported CSR attribute NID: " + nid);
|
||||
}
|
||||
|
||||
if (value == null || value.length == 0) {
|
||||
throw new WolfSSLException(
|
||||
"CSR attribute value may not be null or zero length");
|
||||
}
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
ret = X509_REQ_add1_attr_by_NID(this.x509ReqPtr, nid,
|
||||
MBSTRING_ASC, value);
|
||||
}
|
||||
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new WolfSSLException("Error setting CSR attribute " +
|
||||
"(ret: " + ret + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set CSR version for this WolfSSLCertRequest object.
|
||||
*
|
||||
* Calling this method is optional when generating a CSR. By default,
|
||||
* a value of 0 (zero) is used for the CSR version. This is currently
|
||||
* the version used by all CSR RFCs/specs.
|
||||
*
|
||||
* @param version version to set for CSR
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws WolfSSLException if native JNI error occurs.
|
||||
*/
|
||||
public void setVersion(long version)
|
||||
throws IllegalStateException, WolfSSLException {
|
||||
|
||||
int ret;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
ret = X509_REQ_set_version(this.x509ReqPtr, version);
|
||||
}
|
||||
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new WolfSSLException("Error setting CSR version " +
|
||||
"(ret: " + ret + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set public key for this WolfSSLCertRequest, used when generating
|
||||
* Certificate Signing Requests
|
||||
*
|
||||
* @param filePath Path to public key file
|
||||
* @param keyType Type of public key algorithm, options are:
|
||||
* WolfSSL.RSAk
|
||||
* WolfSSL.ECDSAk
|
||||
* @param format Format of public key file, options are:
|
||||
* WolfSSL.SSL_FILETYPE_ASN1 (DER formatted)
|
||||
* WolfSSL.SSL_FILETYPE_PEM (PEM formatted)
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws IOException on error opening input file
|
||||
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
|
||||
*/
|
||||
public void setPublicKey(String filePath, int keyType, int format)
|
||||
throws IllegalStateException, IOException, WolfSSLException {
|
||||
|
||||
int ret = 0;
|
||||
File keyFile = null;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
if (filePath == null || filePath.isEmpty()) {
|
||||
throw new WolfSSLException("File path is null or empty");
|
||||
}
|
||||
|
||||
keyFile = new File(filePath);
|
||||
if (!keyFile.exists()) {
|
||||
throw new WolfSSLException("Input file does not exist: " +
|
||||
filePath);
|
||||
}
|
||||
|
||||
setPublicKey(Files.readAllBytes(keyFile.toPath()), keyType, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set public key for this WolfSSLCertRequest, used when generating
|
||||
* Certificate Signing Requests
|
||||
*
|
||||
* @param key Byte array containing public key
|
||||
* @param keyType Type of public key algorithm, options are:
|
||||
* WolfSSL.RSAk
|
||||
* WolfSSL.ECDSAk
|
||||
* @param format Format of public key file, options are:
|
||||
* WolfSSL.SSL_FILETYPE_ASN1 (DER formatted)
|
||||
* WolfSSL.SSL_FILETYPE_PEM (PEM formatted)
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws IOException on error opening input file
|
||||
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
|
||||
*/
|
||||
public void setPublicKey(byte[] key, int keyType, int format)
|
||||
throws IllegalStateException, IOException, WolfSSLException {
|
||||
|
||||
int ret = 0;
|
||||
int evpKeyType;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
if (key == null || key.length == 0) {
|
||||
throw new WolfSSLException("Key array is null or empty");
|
||||
}
|
||||
|
||||
if (format != WolfSSL.SSL_FILETYPE_ASN1 &&
|
||||
format != WolfSSL.SSL_FILETYPE_PEM) {
|
||||
throw new WolfSSLException(
|
||||
"Invalid key format, must be PEM or DER");
|
||||
}
|
||||
|
||||
switch (keyType) {
|
||||
case WolfSSL.RSAk:
|
||||
evpKeyType = EVP_PKEY_RSA;
|
||||
break;
|
||||
case WolfSSL.ECDSAk:
|
||||
evpKeyType = EVP_PKEY_EC;
|
||||
break;
|
||||
default:
|
||||
throw new WolfSSLException("Unsupported public key type");
|
||||
}
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
ret = X509_REQ_set_pubkey_native_open(this.x509ReqPtr, evpKeyType,
|
||||
key, format);
|
||||
}
|
||||
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new WolfSSLException(
|
||||
"Error setting public key into native WOLFSSL_X509_REQ " +
|
||||
"(ret: " + ret + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set public key for this WolfSSLCertRequest, used when generating
|
||||
* Certificate Signing Requests
|
||||
*
|
||||
* @param key PublicKey object containing public key to be used when
|
||||
* generating CSR.
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
|
||||
* @throws IOException on error opening/reading public key
|
||||
*/
|
||||
public void setPublicKey(PublicKey key)
|
||||
throws IllegalStateException, IOException, WolfSSLException {
|
||||
|
||||
int keyType;
|
||||
byte[] encodedKey = null;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
if (key instanceof RSAPublicKey) {
|
||||
keyType = WolfSSL.RSAk;
|
||||
}
|
||||
else if (key instanceof ECPublicKey) {
|
||||
keyType = WolfSSL.ECDSAk;
|
||||
}
|
||||
else {
|
||||
throw new WolfSSLException(
|
||||
"PublicKey must be of type RSAPublicKey or ECPublicKey");
|
||||
}
|
||||
|
||||
/* Get DER encoded key */
|
||||
encodedKey = key.getEncoded();
|
||||
if (encodedKey == null) {
|
||||
throw new WolfSSLException(
|
||||
"Error getting encoded (DER) format of PublicKey");
|
||||
}
|
||||
|
||||
setPublicKey(encodedKey, keyType, WolfSSL.SSL_FILETYPE_ASN1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an extension to a WolfSSLCertRequest given the NID and extension
|
||||
* value String.
|
||||
*
|
||||
* This method supports the following extensions:
|
||||
* - Key Usage (WolfSSL.NID_key_usage)
|
||||
* - Extended Key Usage (WolfSSL.NID_ext_key_usage)
|
||||
* - Subject Alt Name (WolfSSL.NED_subject_alt_name)
|
||||
*
|
||||
* @param nid NID of extension to add. Must be one of:
|
||||
* WolfSSL.NID_key_usage
|
||||
* WolfSSL.NID_ext_key_usage
|
||||
* WolfSSL.NID_subject_alt_name
|
||||
* @param value String value of extension to set. For keyUsage and
|
||||
* extKeyUsage this should be a comma-delimited list.
|
||||
* For subjectAltName, this is a single value. Possible
|
||||
* values for keyUsage and extKeyUsage are:
|
||||
*
|
||||
* NID_key_usage:
|
||||
* digitalSignature
|
||||
* nonRepudiation
|
||||
* contentCommitment
|
||||
* keyEncipherment
|
||||
* dataEncipherment
|
||||
* keyAgreement
|
||||
* keyCertSign
|
||||
* cRLSign
|
||||
* encipherOnly
|
||||
* decipherOnly
|
||||
*
|
||||
* NID_ext_key_usage:
|
||||
* serverAuth
|
||||
* clientAuth
|
||||
* codeSigning
|
||||
* emailProtection
|
||||
* timeStamping
|
||||
* OCSPSigning
|
||||
*
|
||||
* @param isCritical Boolean flag indicating if this extension is
|
||||
* critical
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
|
||||
*/
|
||||
public void addExtension(int nid, String value, boolean isCritical)
|
||||
throws IllegalStateException, WolfSSLException {
|
||||
|
||||
int ret = 0;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
if (nid != WolfSSL.NID_key_usage &&
|
||||
nid != WolfSSL.NID_subject_alt_name &&
|
||||
nid != WolfSSL.NID_ext_key_usage) {
|
||||
throw new WolfSSLException(
|
||||
"Unsupported X509v3 extension NID: " + nid);
|
||||
}
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
ret = X509_add_ext_via_nconf_nid(this.x509ReqPtr, nid, value,
|
||||
isCritical);
|
||||
}
|
||||
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
if ((WolfSSL.getLibVersionHex() <= 0x05006003) &&
|
||||
(nid == WolfSSL.NID_key_usage ||
|
||||
nid == WolfSSL.NID_ext_key_usage)) {
|
||||
|
||||
/* wolfSSL versions 5.6.3 and earlier did not include code
|
||||
* fixes to native wolfSSL allowing this extension support to
|
||||
* work. Use a version > 5.6.3 or apply patch from wolfSSL
|
||||
* PR 6585 for correct support */
|
||||
throw new WolfSSLException(
|
||||
"Error setting extension into native WOLFSSL_X509 " +
|
||||
"(ret: " + ret + ").\nNeed to use wolfSSL version " +
|
||||
"greater than 5.6.3 for extension support (PR 6585).");
|
||||
}
|
||||
|
||||
throw new WolfSSLException(
|
||||
"Error setting extension into native WOLFSSL_X509 " +
|
||||
"(ret: " + ret + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an extension to a WolfSSLCertRequest given the NID and extension
|
||||
* value true/false value.
|
||||
*
|
||||
* This method supports the following extensions:
|
||||
* - Basic Constraints (WolfSSL.NID_basic_constraints)
|
||||
*
|
||||
* @param nid NID of extension to add. Must be one of:
|
||||
* WolfSSL.NID_basic_constraints
|
||||
* @param value Boolean value of extension (true/false)
|
||||
* @param isCritical Boolean flag indicating if this extension is
|
||||
* critical
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
|
||||
*/
|
||||
public void addExtension(int nid, boolean value, boolean isCritical)
|
||||
throws IllegalStateException, WolfSSLException {
|
||||
|
||||
int ret = 0;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
if (nid != WolfSSL.NID_basic_constraints) {
|
||||
throw new WolfSSLException(
|
||||
"Unsupported X509v3 extension NID: " + nid);
|
||||
}
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
ret = X509_add_ext_via_set_object_boolean(
|
||||
this.x509ReqPtr, nid, value, isCritical);
|
||||
}
|
||||
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new WolfSSLException(
|
||||
"Error setting extension into native WOLFSSL_X509 " +
|
||||
"(ret: " + ret + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign certificate request with private key from file.
|
||||
*
|
||||
* @param filePath Path to private key file
|
||||
* @param keyType Type of public key algorithm, options are:
|
||||
* WolfSSL.RSAk
|
||||
* WolfSSL.ECDSAk
|
||||
* @param format Format of private key file, options are:
|
||||
* WolfSSL.SSL_FILETYPE_ASN1 (DER formatted)
|
||||
* WolfSSL.SSL_FILETYPE_PEM (PEM formatted)
|
||||
* @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"
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws IOException on error opening input file
|
||||
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
|
||||
*/
|
||||
public void signRequest(String filePath, int keyType, int format,
|
||||
String digestAlg) throws IllegalStateException, IOException,
|
||||
WolfSSLException {
|
||||
|
||||
int ret = 0;
|
||||
File keyFile = null;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
if (filePath == null || filePath.isEmpty()) {
|
||||
throw new WolfSSLException("File path is null or empty");
|
||||
}
|
||||
|
||||
keyFile = new File(filePath);
|
||||
if (!keyFile.exists()) {
|
||||
throw new WolfSSLException("Input file does not exist: " +
|
||||
filePath);
|
||||
}
|
||||
|
||||
signRequest(Files.readAllBytes(keyFile.toPath()), keyType,
|
||||
format, digestAlg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign certificate request with private key from buffer.
|
||||
*
|
||||
* @param key Byte array containing private key
|
||||
* @param keyType Type of public key algorithm, options are:
|
||||
* WolfSSL.RSAk
|
||||
* WolfSSL.ECDSAk
|
||||
* @param format Format of private key file, options are:
|
||||
* WolfSSL.SSL_FILETYPE_ASN1 (DER formatted)
|
||||
* WolfSSL.SSL_FILETYPE_PEM (PEM formatted)
|
||||
* @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"
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
|
||||
*/
|
||||
public void signRequest(byte[] key, int keyType, int format,
|
||||
String digestAlg) throws IllegalStateException, WolfSSLException {
|
||||
|
||||
int ret = 0;
|
||||
int evpKeyType;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
if (key == null || key.length == 0) {
|
||||
throw new WolfSSLException("Key array is null or empty");
|
||||
}
|
||||
|
||||
if (format != WolfSSL.SSL_FILETYPE_ASN1 &&
|
||||
format != WolfSSL.SSL_FILETYPE_PEM) {
|
||||
throw new WolfSSLException(
|
||||
"Invalid key format, must be PEM or DER");
|
||||
}
|
||||
|
||||
switch (keyType) {
|
||||
case WolfSSL.RSAk:
|
||||
evpKeyType = EVP_PKEY_RSA;
|
||||
break;
|
||||
case WolfSSL.ECDSAk:
|
||||
evpKeyType = EVP_PKEY_EC;
|
||||
break;
|
||||
default:
|
||||
throw new WolfSSLException("Unsupported private key type");
|
||||
}
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
ret = X509_REQ_sign(this.x509ReqPtr, evpKeyType, key, format,
|
||||
digestAlg);
|
||||
}
|
||||
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new WolfSSLException(
|
||||
"Error signing native X509_REQ " +
|
||||
"(ret: " + ret + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign certificate request 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"
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws WolfSSLException if invalid arguments or native JNI error occurs.
|
||||
*/
|
||||
public void signRequest(PrivateKey key, String digestAlg)
|
||||
throws IllegalStateException, WolfSSLException {
|
||||
|
||||
int ret = 0;
|
||||
int evpKeyType;
|
||||
byte[] encodedKey = null;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
if (key == null) {
|
||||
throw new WolfSSLException("Key object is null");
|
||||
}
|
||||
|
||||
if (key instanceof RSAPrivateKey) {
|
||||
evpKeyType = EVP_PKEY_RSA;
|
||||
}
|
||||
else if (key instanceof ECPrivateKey) {
|
||||
evpKeyType = EVP_PKEY_EC;
|
||||
}
|
||||
else {
|
||||
throw new WolfSSLException(
|
||||
"PrivateKey must be of type RSAPrivateKey or ECPrivateKey");
|
||||
}
|
||||
|
||||
/* Get DER encoded key */
|
||||
encodedKey = key.getEncoded();
|
||||
if (encodedKey == null) {
|
||||
throw new WolfSSLException("PrivateKey does not support encoding");
|
||||
}
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
ret = X509_REQ_sign(this.x509ReqPtr, evpKeyType, encodedKey,
|
||||
WolfSSL.SSL_FILETYPE_ASN1, digestAlg);
|
||||
}
|
||||
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new WolfSSLException(
|
||||
"Error signing native X509_REQ " +
|
||||
"(ret: " + ret + ")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ASN.1/DER encoding of this CSR, after signRequest() has been called.
|
||||
*
|
||||
* @return DER encoded array of CSR or null if not available.
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws WolfSSLJNIException if native JNI operation fails
|
||||
*/
|
||||
public byte[] getDer() throws IllegalStateException, WolfSSLJNIException {
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
return X509_REQ_get_der(this.x509ReqPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PEM encoding of this CSR, after signRequest() has been called.
|
||||
*
|
||||
* @return PEM encoded array of CSR or null if not available.
|
||||
*
|
||||
* @throws IllegalStateException if WolfSSLCertRequest has been freed.
|
||||
* @throws WolfSSLJNIException if native JNI operation fails
|
||||
*/
|
||||
public byte[] getPem() throws IllegalStateException, WolfSSLJNIException {
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
return X509_REQ_get_pem(this.x509ReqPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
byte[] x509ReqText = null;
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (this.active == false) {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
x509ReqText = X509_REQ_print(this.x509ReqPtr);
|
||||
}
|
||||
if (x509ReqText != null) {
|
||||
/* let Java do the modified UTF-8 conversion */
|
||||
return new String(x509ReqText, Charset.forName("UTF-8"));
|
||||
} else {
|
||||
System.out.println("toString: x509ReqTest == null");
|
||||
}
|
||||
}
|
||||
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees WolfSSLCertRequest native resources.
|
||||
*/
|
||||
public synchronized void free() {
|
||||
|
||||
synchronized (stateLock) {
|
||||
if (this.active == false) {
|
||||
/* already freed, just return */
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (x509ReqLock) {
|
||||
/* free native resources */
|
||||
X509_REQ_free(this.x509ReqPtr);
|
||||
|
||||
/* free Java resources */
|
||||
this.active = false;
|
||||
this.x509ReqPtr = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
protected void finalize() throws Throwable
|
||||
{
|
||||
this.free();
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
|
@ -730,7 +730,32 @@ public class WolfSSLCertificate {
|
|||
* @param nid NID of extension to add. Must be one of:
|
||||
* WolfSSL.NID_key_usage
|
||||
* WolfSSL.NID_subject_alt_name
|
||||
* @param value String value of extension to set
|
||||
* WolfSSL.NID_subject_alt_name
|
||||
* @param value String value of extension to set. For keyUsage and
|
||||
* extKeyUsage this should be a comma-delimited list.
|
||||
* For subjectAltName, this is a single value. Possible
|
||||
* values for keyUsage and extKeyUsage are:
|
||||
*
|
||||
* NID_key_usage:
|
||||
* digitalSignature
|
||||
* nonRepudiation
|
||||
* contentCommitment
|
||||
* keyEncipherment
|
||||
* dataEncipherment
|
||||
* keyAgreement
|
||||
* keyCertSign
|
||||
* cRLSign
|
||||
* encipherOnly
|
||||
* decipherOnly
|
||||
*
|
||||
* NID_ext_key_usage:
|
||||
* serverAuth
|
||||
* clientAuth
|
||||
* codeSigning
|
||||
* emailProtection
|
||||
* timeStamping
|
||||
* OCSPSigning
|
||||
*
|
||||
* @param isCritical Boolean flag indicating if this extension is
|
||||
* critical
|
||||
*
|
||||
|
@ -785,8 +810,7 @@ public class WolfSSLCertificate {
|
|||
* - Basic Constraints (WolfSSL.NID_basic_constraints)
|
||||
*
|
||||
* @param nid NID of extension to add. Must be one of:
|
||||
* WolfSSL.NID_key_usage
|
||||
* WolfSSL.NID_subject_alt_name
|
||||
* WolfSSL.NID_basic_constraints
|
||||
* @param value Boolean value of extension (true/false)
|
||||
* @param isCritical Boolean flag indicating if this extension is
|
||||
* critical
|
||||
|
|
|
@ -0,0 +1,608 @@
|
|||
/* WolfSSLCertRequestTest.java
|
||||
*
|
||||
* Copyright (C) 2006-2023 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 org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
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.PublicKey;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
import com.wolfssl.WolfSSL;
|
||||
import com.wolfssl.WolfSSLX509Name;
|
||||
import com.wolfssl.WolfSSLCertRequest;
|
||||
import com.wolfssl.WolfSSLException;
|
||||
import com.wolfssl.WolfSSLJNIException;
|
||||
|
||||
/**
|
||||
* @author wolfSSL
|
||||
*/
|
||||
public class WolfSSLCertRequestTest {
|
||||
public final static int TEST_FAIL = -1;
|
||||
public final static int TEST_SUCCESS = 0;
|
||||
|
||||
public static String cliKeyDer = "examples/certs/client-key.der";
|
||||
public static String cliKeyPem = "examples/certs/client-key.pem";
|
||||
public static String cliKeyPubDer = "examples/certs/client-keyPub.der";
|
||||
public static String cliEccKeyDer = "examples/certs/ecc-client-key.der";
|
||||
public static String cliEccKeyPem = "examples/certs/ecc-client-key.pem";
|
||||
|
||||
@BeforeClass
|
||||
public static void setCertPaths() throws WolfSSLException {
|
||||
|
||||
System.out.println("WolfSSLCertRequest Class");
|
||||
|
||||
try {
|
||||
WolfSSL.loadLibrary();
|
||||
} catch (UnsatisfiedLinkError ule) {
|
||||
fail("failed to load native JNI library");
|
||||
}
|
||||
|
||||
cliKeyDer = WolfSSLTestCommon.getPath(cliKeyDer);
|
||||
cliKeyPubDer = WolfSSLTestCommon.getPath(cliKeyPubDer);
|
||||
}
|
||||
|
||||
/* Internal helper method, generate test SubjectName for cert generation */
|
||||
private WolfSSLX509Name GenerateTestSubjectName() throws WolfSSLException {
|
||||
|
||||
WolfSSLX509Name name = new WolfSSLX509Name();
|
||||
|
||||
name.setCountryName("US");
|
||||
name.setStateOrProvinceName("Montana");
|
||||
name.setStreetAddress("12345 Test Address");
|
||||
name.setLocalityName("Bozeman");
|
||||
name.setSurname("Test Surname");
|
||||
name.setCommonName("wolfssl.com");
|
||||
name.setEmailAddress("support@wolfssl.com");
|
||||
name.setOrganizationName("wolfSSL Inc.");
|
||||
name.setOrganizationalUnitName("Development Test");
|
||||
name.setUserId("TestUserID");
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddAttribute()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\taddAttribute()");
|
||||
|
||||
if (!WolfSSL.certReqEnabled()) {
|
||||
/* WOLFSSL_CERT_REQ / --enable-certreq not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCertRequest req = new WolfSSLCertRequest();
|
||||
assertNotNull(req);
|
||||
|
||||
/* Test adding supported attributes by NID */
|
||||
req.addAttribute(WolfSSL.NID_pkcs9_challengePassword,
|
||||
"12345".getBytes());
|
||||
req.addAttribute(WolfSSL.NID_serialNumber,
|
||||
"12345".getBytes());
|
||||
req.addAttribute(WolfSSL.NID_pkcs9_unstructuredName,
|
||||
"12345".getBytes());
|
||||
req.addAttribute(WolfSSL.NID_pkcs9_contentType,
|
||||
"12345".getBytes());
|
||||
req.addAttribute(WolfSSL.NID_surname,
|
||||
"12345".getBytes());
|
||||
req.addAttribute(WolfSSL.NID_initials,
|
||||
"12345".getBytes());
|
||||
req.addAttribute(WolfSSL.NID_givenName,
|
||||
"12345".getBytes());
|
||||
req.addAttribute(WolfSSL.NID_dnQualifier,
|
||||
"12345".getBytes());
|
||||
|
||||
/* Adding unsupported NID should throw exception */
|
||||
try {
|
||||
req.addAttribute(123456,
|
||||
"12345".getBytes());
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("Unsupported NID did not throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
req.free();
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddExtension()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\taddExtension()");
|
||||
|
||||
if (!WolfSSL.certReqEnabled()) {
|
||||
/* WOLFSSL_CERT_REQ / --enable-certreq not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCertRequest req = new WolfSSLCertRequest();
|
||||
assertNotNull(req);
|
||||
|
||||
/* Test adding supported extensions by NID */
|
||||
|
||||
/* wolfSSL versions 5.6.3 and earlier did not include code
|
||||
* fixes to native wolfSSL allowing this extension support to
|
||||
* work. Use a version > 5.6.3 or apply patch from wolfSSL
|
||||
* PR 6585 for correct support */
|
||||
if (WolfSSL.getLibVersionHex() <= 0x05006003) {
|
||||
req.addExtension(WolfSSL.NID_key_usage,
|
||||
"digitalSignature,keyAgreement", false);
|
||||
req.addExtension(WolfSSL.NID_ext_key_usage,
|
||||
"serverAuth,clientAuth", false);
|
||||
}
|
||||
req.addExtension(WolfSSL.NID_subject_alt_name,
|
||||
"my test altName", false);
|
||||
|
||||
/* Adding unsupported NID should throw exception */
|
||||
try {
|
||||
req.addExtension(123456, "12345", false);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("Unsupported extension NID did not throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Test boolean extension setting */
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, true, true);
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, false, true);
|
||||
|
||||
/* Adding unsupported NID should throw exception */
|
||||
try {
|
||||
req.addExtension(123456, true, false);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("Unsupported extension NID did not throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
req.free();
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetVersion()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\tsetVersion()");
|
||||
|
||||
if (!WolfSSL.certReqEnabled()) {
|
||||
/* WOLFSSL_CERT_REQ / --enable-certreq not enabled in wolfSSL */
|
||||
System.out.println("\t\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCertRequest req = new WolfSSLCertRequest();
|
||||
assertNotNull(req);
|
||||
|
||||
req.setVersion(0);
|
||||
req.setVersion(1);
|
||||
|
||||
/* Negative versions should throw exception */
|
||||
try {
|
||||
req.setVersion(-100);
|
||||
System.out.println("\t\t\t... failed");
|
||||
fail("Negative version should throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
req.free();
|
||||
System.out.println("\t\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetPublicKeyFile()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\tsetPublicKey(file)");
|
||||
|
||||
if (!WolfSSL.certReqEnabled()) {
|
||||
/* WOLFSSL_CERT_REQ / --enable-certreq not enabled in wolfSSL */
|
||||
System.out.println("\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCertRequest req = new WolfSSLCertRequest();
|
||||
assertNotNull(req);
|
||||
|
||||
/* RSA */
|
||||
req.setPublicKey(cliKeyPubDer, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
req.setPublicKey(cliKeyPem, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_PEM);
|
||||
|
||||
/* ECC */
|
||||
req.setPublicKey(cliEccKeyDer, WolfSSL.ECDSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
req.setPublicKey(cliEccKeyPem, WolfSSL.ECDSAk,
|
||||
WolfSSL.SSL_FILETYPE_PEM);
|
||||
|
||||
/* Test bad key type */
|
||||
try {
|
||||
req.setPublicKey(cliKeyPubDer, 12345,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
System.out.println("\t\t... failed");
|
||||
fail("bad key type should throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Test bad file type */
|
||||
try {
|
||||
req.setPublicKey(cliKeyPubDer, WolfSSL.RSAk, 12345);
|
||||
System.out.println("\t\t... failed");
|
||||
fail("bad file type should throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Test null file String */
|
||||
try {
|
||||
req.setPublicKey((String)null, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
System.out.println("\t\t... failed");
|
||||
fail("null PublicKey should throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Test file that does not exist */
|
||||
try {
|
||||
req.setPublicKey("badfile", WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
System.out.println("\t\t... failed");
|
||||
fail("Bad path to PublicKey should throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
req.free();
|
||||
System.out.println("\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetPublicKeyArray()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\tsetPublicKey(array)");
|
||||
|
||||
if (!WolfSSL.certReqEnabled()) {
|
||||
/* WOLFSSL_CERT_REQ / --enable-certreq not enabled in wolfSSL */
|
||||
System.out.println("\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCertRequest req = new WolfSSLCertRequest();
|
||||
assertNotNull(req);
|
||||
|
||||
byte[] cliKeyRSADer = Files.readAllBytes(Paths.get(cliKeyDer));
|
||||
byte[] cliKeyRSAPem = Files.readAllBytes(Paths.get(cliKeyPem));
|
||||
byte[] cliKeyECCDer = Files.readAllBytes(Paths.get(cliEccKeyDer));
|
||||
byte[] cliKeyECCPem = Files.readAllBytes(Paths.get(cliEccKeyPem));
|
||||
|
||||
/* RSA */
|
||||
req.setPublicKey(cliKeyRSADer, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
req.setPublicKey(cliKeyRSAPem, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_PEM);
|
||||
|
||||
/* ECC */
|
||||
req.setPublicKey(cliKeyECCDer, WolfSSL.ECDSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
req.setPublicKey(cliKeyECCPem, WolfSSL.ECDSAk,
|
||||
WolfSSL.SSL_FILETYPE_PEM);
|
||||
|
||||
/* Test bad key type */
|
||||
try {
|
||||
req.setPublicKey(cliKeyRSADer, 12345,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
System.out.println("\t\t... failed");
|
||||
fail("bad key type should throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Test bad file type */
|
||||
try {
|
||||
req.setPublicKey(cliKeyRSADer, WolfSSL.RSAk, 12345);
|
||||
System.out.println("\t\t... failed");
|
||||
fail("bad file type should throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Test null file String */
|
||||
try {
|
||||
req.setPublicKey((byte[])null, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
System.out.println("\t\t... failed");
|
||||
fail("null key array should throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Test zero-length byte array */
|
||||
byte[] zeroArr = new byte[0];
|
||||
try {
|
||||
req.setPublicKey(zeroArr, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
System.out.println("\t\t... failed");
|
||||
fail("Zero length pub key array should throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
req.free();
|
||||
System.out.println("\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetPublicKeyObject()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
|
||||
System.out.print("\tsetPublicKey(PublicKey)");
|
||||
|
||||
if (!WolfSSL.certReqEnabled()) {
|
||||
/* WOLFSSL_CERT_REQ / --enable-certreq not enabled in wolfSSL */
|
||||
System.out.println("\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCertRequest req = new WolfSSLCertRequest();
|
||||
assertNotNull(req);
|
||||
|
||||
/* RSA: Set Public Key from generated java.security.PublicKey */
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
|
||||
kpg.initialize(2048);
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
PublicKey pubKey = keyPair.getPublic();
|
||||
req.setPublicKey(pubKey);
|
||||
|
||||
/* ECC: Set Public Key from generated java.security.PublicKey */
|
||||
KeyPairGenerator kpgEcc = KeyPairGenerator.getInstance("EC");
|
||||
kpgEcc.initialize(256);
|
||||
KeyPair keyPairEcc = kpgEcc.generateKeyPair();
|
||||
PublicKey pubKeyEcc = keyPairEcc.getPublic();
|
||||
req.setPublicKey(pubKeyEcc);
|
||||
|
||||
/* Test null PublicKey object */
|
||||
try {
|
||||
req.setPublicKey((PublicKey)null);
|
||||
System.out.println("\t\t... failed");
|
||||
fail("null PublicKey should throw exception");
|
||||
} catch (WolfSSLException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
req.free();
|
||||
System.out.println("\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenCSR_UsingFiles()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\tgen CSR using files");
|
||||
|
||||
if (!WolfSSL.certReqEnabled()) {
|
||||
/* WOLFSSL_CERT_REQ / --enable-certreq not enabled in wolfSSL */
|
||||
System.out.println("\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCertRequest req = new WolfSSLCertRequest();
|
||||
assertNotNull(req);
|
||||
|
||||
/* Set Subject Name */
|
||||
WolfSSLX509Name subjectName = GenerateTestSubjectName();
|
||||
assertNotNull(subjectName);
|
||||
req.setSubjectName(subjectName);
|
||||
|
||||
/* Set Public Key from file */
|
||||
req.setPublicKey(cliKeyPubDer, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1);
|
||||
|
||||
/* Set Extensions */
|
||||
if (WolfSSL.getLibVersionHex() > 0x05006003) {
|
||||
/* Key Usage and Extended Key Usage only work with wolfSSL
|
||||
* later than 5.6.3 */
|
||||
req.addExtension(WolfSSL.NID_key_usage,
|
||||
"digitalSignature,keyEncipherment,dataEncipherment", false);
|
||||
|
||||
req.addExtension(WolfSSL.NID_ext_key_usage,
|
||||
"clientAuth,serverAuth", false);
|
||||
}
|
||||
req.addExtension(WolfSSL.NID_subject_alt_name,
|
||||
"test.wolfssl.com", false);
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, true, true);
|
||||
|
||||
/* Sign CSR */
|
||||
req.signRequest(cliKeyDer, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1, "SHA256");
|
||||
|
||||
/* Output to DER and PEM */
|
||||
byte[] derCsr = req.getDer();
|
||||
byte[] pemCsr = req.getPem();
|
||||
|
||||
assertNotNull(derCsr);
|
||||
assertTrue(derCsr.length > 0);
|
||||
assertNotNull(pemCsr);
|
||||
assertTrue(pemCsr.length > 0);
|
||||
|
||||
/* Free native memory */
|
||||
subjectName.free();
|
||||
req.free();
|
||||
|
||||
System.out.println("\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenCSR_UsingBuffers()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException {
|
||||
|
||||
System.out.print("\tgen CSR using buffers");
|
||||
|
||||
if (!WolfSSL.certReqEnabled()) {
|
||||
/* WOLFSSL_CERT_REQ / --enable-certreq not enabled in wolfSSL */
|
||||
System.out.println("\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCertRequest req = new WolfSSLCertRequest();
|
||||
assertNotNull(req);
|
||||
|
||||
/* Set Subject Name */
|
||||
WolfSSLX509Name subjectName = GenerateTestSubjectName();
|
||||
assertNotNull(subjectName);
|
||||
req.setSubjectName(subjectName);
|
||||
|
||||
/* Set Public Key from file */
|
||||
byte[] pubKey = Files.readAllBytes(Paths.get(cliKeyPubDer));
|
||||
req.setPublicKey(pubKey, WolfSSL.RSAk, WolfSSL.SSL_FILETYPE_ASN1);
|
||||
|
||||
/* Set Extensions */
|
||||
if (WolfSSL.getLibVersionHex() > 0x05006003) {
|
||||
/* Key Usage and Extended Key Usage only work with wolfSSL
|
||||
* later than 5.6.3 */
|
||||
req.addExtension(WolfSSL.NID_key_usage,
|
||||
"digitalSignature,keyEncipherment,dataEncipherment", false);
|
||||
req.addExtension(WolfSSL.NID_ext_key_usage,
|
||||
"clientAuth,serverAuth", false);
|
||||
}
|
||||
req.addExtension(WolfSSL.NID_subject_alt_name,
|
||||
"test.wolfssl.com", false);
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, true, true);
|
||||
|
||||
/* Sign CSR */
|
||||
byte[] privKey = Files.readAllBytes(Paths.get(cliKeyDer));
|
||||
req.signRequest(privKey, WolfSSL.RSAk,
|
||||
WolfSSL.SSL_FILETYPE_ASN1, "SHA256");
|
||||
|
||||
/* Output to DER and PEM */
|
||||
byte[] derCsr = req.getDer();
|
||||
byte[] pemCsr = req.getPem();
|
||||
|
||||
assertNotNull(derCsr);
|
||||
assertTrue(derCsr.length > 0);
|
||||
assertNotNull(pemCsr);
|
||||
assertTrue(pemCsr.length > 0);
|
||||
|
||||
/* Free native memory */
|
||||
subjectName.free();
|
||||
req.free();
|
||||
|
||||
System.out.println("\t\t... passed");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenCSR_UsingJavaClasses()
|
||||
throws WolfSSLException, WolfSSLJNIException, IOException,
|
||||
CertificateException, NoSuchAlgorithmException {
|
||||
|
||||
System.out.print("\tgen CSR using Java classes");
|
||||
|
||||
if (!WolfSSL.certReqEnabled()) {
|
||||
/* WOLFSSL_CERT_REQ / --enable-certreq not enabled in wolfSSL */
|
||||
System.out.println("\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
WolfSSLCertRequest req = new WolfSSLCertRequest();
|
||||
assertNotNull(req);
|
||||
|
||||
/* Set Subject Name */
|
||||
WolfSSLX509Name subjectName = GenerateTestSubjectName();
|
||||
assertNotNull(subjectName);
|
||||
req.setSubjectName(subjectName);
|
||||
|
||||
/* Set Public Key from generated java.security.PublicKey */
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
|
||||
kpg.initialize(2048);
|
||||
KeyPair keyPair = kpg.generateKeyPair();
|
||||
PublicKey pubKey = keyPair.getPublic();
|
||||
req.setPublicKey(pubKey);
|
||||
|
||||
/* Set Extensions */
|
||||
if (WolfSSL.getLibVersionHex() > 0x05006003) {
|
||||
/* Key Usage and Extended Key Usage only work with wolfSSL
|
||||
* later than 5.6.3 */
|
||||
req.addExtension(WolfSSL.NID_key_usage,
|
||||
"digitalSignature,keyEncipherment,dataEncipherment", false);
|
||||
req.addExtension(WolfSSL.NID_ext_key_usage,
|
||||
"clientAuth,serverAuth", false);
|
||||
}
|
||||
req.addExtension(WolfSSL.NID_subject_alt_name,
|
||||
"test.wolfssl.com", false);
|
||||
req.addExtension(WolfSSL.NID_basic_constraints, true, true);
|
||||
|
||||
/* Sign CSR, with java.security.PrivateKey */
|
||||
PrivateKey privKey = keyPair.getPrivate();
|
||||
req.signRequest(privKey, "SHA256");
|
||||
|
||||
/* Output to DER and PEM */
|
||||
byte[] derCsr = req.getDer();
|
||||
byte[] pemCsr = req.getPem();
|
||||
|
||||
assertNotNull(derCsr);
|
||||
assertTrue(derCsr.length > 0);
|
||||
assertNotNull(pemCsr);
|
||||
assertTrue(pemCsr.length > 0);
|
||||
|
||||
/* Free native memory */
|
||||
subjectName.free();
|
||||
req.free();
|
||||
|
||||
System.out.println("\t... passed");
|
||||
}
|
||||
|
||||
/* Utility method if needed for testing, print out CSR array to file */
|
||||
private void writeOutCsrFile(byte[] csr, String path)
|
||||
throws IOException {
|
||||
Files.write(new File(path).toPath(), csr);
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,8 @@ import org.junit.runners.Suite;
|
|||
WolfSSLSessionTest.class,
|
||||
WolfCryptRSATest.class,
|
||||
WolfCryptECCTest.class,
|
||||
WolfSSLCertificateTest.class
|
||||
WolfSSLCertificateTest.class,
|
||||
WolfSSLCertRequestTest.class
|
||||
})
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue