diff --git a/.gitignore b/.gitignore
index 0f7b6e2..9e43ca8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,6 +25,7 @@ IDE/WIN/DLL Debug
IDE/WIN/DLL Debug FIPS
IDE/WIN/DLL Release
IDE/WIN/DLL Release FIPS
+examples/certs/generated
# RPM package files
rpm/spec
diff --git a/IDE/WIN/wolfssljni.vcxproj b/IDE/WIN/wolfssljni.vcxproj
index 8d91e01..68285ef 100644
--- a/IDE/WIN/wolfssljni.vcxproj
+++ b/IDE/WIN/wolfssljni.vcxproj
@@ -43,6 +43,7 @@
+
@@ -55,6 +56,7 @@
+
diff --git a/IDE/WIN/wolfssljni.vcxproj.filters b/IDE/WIN/wolfssljni.vcxproj.filters
index e911186..c330006 100644
--- a/IDE/WIN/wolfssljni.vcxproj.filters
+++ b/IDE/WIN/wolfssljni.vcxproj.filters
@@ -42,6 +42,9 @@
Source Files
+
+ Source Files
+
@@ -77,5 +80,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/examples/README.md b/examples/README.md
index cf48f3c..6ab988d 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -41,6 +41,28 @@ argument:
$ ./examples/server.sh --help
```
+## X509v3 Certificate Generation Example
+
+An example is included which will generate self-signed and CA-signed
+X.509v3 certificates using the wolfSSL JNI library `WolfSSLCertificate`
+class.
+
+**X509v3CertificateGeneration.java** - Certificate generation example
+
+This example is compiled when the `ant examples` target is executed, and can
+be run afterwards with the provided bash script:
+
+```
+$ cd
+$ ./examples/X509v3CertificateGeneration.sh
+```
+
+This will write out generated certificates to the following directory:
+
+```
+examples/certs/generated/
+```
+
## Support
Please contact the wolfSSL support team at support@wolfssl.com with any
diff --git a/examples/X509v3CertificateGeneration.java b/examples/X509v3CertificateGeneration.java
new file mode 100644
index 0000000..d365c66
--- /dev/null
+++ b/examples/X509v3CertificateGeneration.java
@@ -0,0 +1,690 @@
+/* X509v3CertificateGeneration.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.*;
+import java.net.*;
+import java.nio.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.time.Instant;
+import java.time.Duration;
+import java.util.Date;
+import java.math.BigInteger;
+
+import java.io.FileInputStream;
+import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
+import java.security.KeyPair;
+import java.security.PublicKey;
+import java.security.PrivateKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateException;
+
+import com.wolfssl.WolfSSL;
+import com.wolfssl.WolfSSLCertificate;
+import com.wolfssl.WolfSSLX509Name;
+import com.wolfssl.WolfSSLException;
+import com.wolfssl.WolfSSLJNIException;
+
+/**
+ * Example application that demonstrates X509v3 certifiate generation
+ * including various combinations:
+ *
+ * Self-signed certificate using files as input for certs/keys
+ * Self-signed certificate using arrays as input for certs/keys
+ * Self-signed certificate using generated certs and keys
+ *
+ * CA-signed certificate using files as input for certs/keys
+ * CA-signed certificate using arrays as input for certs/keys
+ * CA-signed certificate 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 X509v3CertificateGeneration {
+
+ 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 cert gen example with files */
+ private static String caCertPem = CERT_DIR + "ca-cert.pem";
+ private static String caKeyDer = CERT_DIR + "ca-key.der";
+ private static String caKeyPkcs8Der = CERT_DIR + "ca-keyPkcs8.der";
+ private static String clientKeyDer = CERT_DIR + "client-key.der";
+ private static String clientKeyPubDer = CERT_DIR + "client-keyPub.der";
+
+ /* Generated self-signed certificate locations.
+ * Generated self-signed certs have isCA Basic Constraint set true
+ * in these examples. */
+ private static String selfSignedUsingFilesDer =
+ GEN_DIR + "self-signed-using-files.der";
+ private static String selfSignedUsingFilesPem =
+ GEN_DIR + "self-signed-using-files.pem";
+ private static String selfSignedUsingArraysDer =
+ GEN_DIR + "self-signed-using-arrays.der";
+ private static String selfSignedUsingArraysPem =
+ GEN_DIR + "self-signed-using-arrays.pem";
+ private static String selfSignedUsingGeneratedKeysDer =
+ GEN_DIR + "self-signed-generated-keys.der";
+ private static String selfSignedUsingGeneratedKeysPem =
+ GEN_DIR + "self-signed-generated-keys.pem";
+
+ /* Generated CA-signed certificate locations.
+ * Generated CA-signed certs have isCA Basic Constraint set false
+ * in these examples. */
+ private static String caSignedUsingFilesDer =
+ GEN_DIR + "ca-signed-using-files.der";
+ private static String caSignedUsingFilesPem =
+ GEN_DIR + "ca-signed-using-files.pem";
+ private static String caSignedUsingArraysDer =
+ GEN_DIR + "ca-signed-using-arrays.der";
+ private static String caSignedUsingArraysPem =
+ GEN_DIR + "ca-signed-using-arrays.pem";
+ private static String caSignedUsingGeneratedKeysDer =
+ GEN_DIR + "ca-signed-generated-keys.der";
+ private static String caSignedUsingGeneratedKeysPem =
+ GEN_DIR + "ca-signed-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";
+
+ 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 using the following files as input
+ * to the certificate generation process:
+ *
+ * clientKeyPubDer - Existing client public key in DER format
+ * clientKeyDer - Existing client private key in DER format
+ *
+ * Generates and writes certificate out to the following paths in
+ * both PEM and DER format (see variable values above):
+ * selfSignedUsingFilesDer (DER format)
+ * selfSignedUsingFilesPem (PEM format)
+ *
+ * @throws WolfSSLException if error occurs during certificate generation
+ * process.
+ * @throws WolfSSLJNIException if native JNI error occurs
+ * @throws IOException on error writing to output file locations
+ */
+ public void generateSelfSignedUsingFiles()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException {
+
+ System.out.print("\nGenerating self-signed cert using files");
+
+ /* Create new certificate object */
+ WolfSSLCertificate x509 = new WolfSSLCertificate();
+
+ /* Set notBefore/notAfter validity dates */
+ Instant now = Instant.now();
+ final Date notBefore = Date.from(now);
+ final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
+ x509.setNotBefore(notBefore);
+ x509.setNotAfter(notAfter);
+
+ /* Set serial number */
+ x509.setSerialNumber(BigInteger.valueOf(12345));
+
+ /* Set Subject Name */
+ WolfSSLX509Name subjectName = generateTestSubjectName();
+ x509.setSubjectName(subjectName);
+
+ /* Not setting Issuer, since generating self-signed cert */
+
+ /* Set Public Key from existing public key DER file */
+ x509.setPublicKey(clientKeyPubDer, WolfSSL.RSAk,
+ WolfSSL.SSL_FILETYPE_ASN1);
+
+ /* Add Extensions */
+ x509.addExtension(WolfSSL.NID_key_usage, test_KEY_USAGE, false);
+ x509.addExtension(WolfSSL.NID_ext_key_usage, test_EXT_KEY_USAGE, false);
+ x509.addExtension(WolfSSL.NID_subject_alt_name, test_ALT_NAME, false);
+ x509.addExtension(WolfSSL.NID_basic_constraints, true, true);
+
+ /* Sign certificate, self-signed using existing client key DER */
+ x509.signCert(clientKeyDer, WolfSSL.RSAk,
+ WolfSSL.SSL_FILETYPE_ASN1, "SHA256");
+
+ /* Output to DER and PEM files */
+ byte[] derCert = x509.getDer();
+ byte[] pemCert = x509.getPem();
+
+ /* Write out generated certs to files */
+ writeFile(selfSignedUsingFilesDer, derCert);
+ writeFile(selfSignedUsingFilesPem, pemCert);
+
+ /* Test converting to X509Certificate */
+ X509Certificate tmpX509 = x509.getX509Certificate();
+
+ System.out.println("... ");
+ System.out.println(" " + CERT_DIR_FROM_ROOT +
+ Paths.get(selfSignedUsingFilesDer).getFileName());
+ System.out.println(" " + CERT_DIR_FROM_ROOT +
+ Paths.get(selfSignedUsingFilesPem).getFileName());
+
+ /* Free native memory */
+ subjectName.free();
+ x509.free();
+ }
+
+ /**
+ * Generate example certificate using the following files in array format
+ * as input to the certificate generation process:
+ *
+ * clientKeyPubDer - Existing client public key in DER format
+ * clientKeyDer - Existing client private key in DER format
+ *
+ * Generates and writes certificate out to the following paths in
+ * both PEM and DER format (see variable values above):
+ * selfSignedUsingArraysDer (DER format)
+ * selfSignedUsingArraysPem (PEM format)
+ *
+ * @throws WolfSSLException if error occurs during certificate generation
+ * process.
+ * @throws WolfSSLJNIException if native JNI error occurs
+ * @throws IOException on error writing to output file locations
+ */
+ public void generateSelfSignedUsingArrays()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException {
+
+ System.out.print("\nGenerating self-signed cert using arrays");
+
+ /* Create new certificate object */
+ WolfSSLCertificate x509 = new WolfSSLCertificate();
+
+ /* Set notBefore/notAfter validity dates */
+ Instant now = Instant.now();
+ final Date notBefore = Date.from(now);
+ final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
+ x509.setNotBefore(notBefore);
+ x509.setNotAfter(notAfter);
+
+ /* Set serial number */
+ x509.setSerialNumber(BigInteger.valueOf(12345));
+
+ /* Set Subject Name */
+ WolfSSLX509Name subjectName = generateTestSubjectName();
+ x509.setSubjectName(subjectName);
+
+ /* Not setting Issuer, since generating self-signed cert */
+
+ /* Set Public Key from existing public key DER file */
+ byte[] pubKey = Files.readAllBytes(Paths.get(clientKeyPubDer));
+ x509.setPublicKey(pubKey, WolfSSL.RSAk, WolfSSL.SSL_FILETYPE_ASN1);
+
+ /* Add Extensions */
+ x509.addExtension(WolfSSL.NID_key_usage, test_KEY_USAGE, false);
+ x509.addExtension(WolfSSL.NID_ext_key_usage, test_EXT_KEY_USAGE, false);
+ x509.addExtension(WolfSSL.NID_subject_alt_name, test_ALT_NAME, false);
+ x509.addExtension(WolfSSL.NID_basic_constraints, true, true);
+
+ /* Sign certificate, self-signed using existing client key DER */
+ byte[] privKey = Files.readAllBytes(Paths.get(clientKeyDer));
+ x509.signCert(privKey, WolfSSL.RSAk,
+ WolfSSL.SSL_FILETYPE_ASN1, "SHA256");
+
+ /* Output to DER and PEM files */
+ byte[] derCert = x509.getDer();
+ byte[] pemCert = x509.getPem();
+
+ /* Write out generated certs to files */
+ writeFile(selfSignedUsingArraysDer, derCert);
+ writeFile(selfSignedUsingArraysPem, pemCert);
+
+ /* Test converting to X509Certificate */
+ X509Certificate tmpX509 = x509.getX509Certificate();
+
+ System.out.println("... ");
+ System.out.println(" " + CERT_DIR_FROM_ROOT +
+ Paths.get(selfSignedUsingArraysDer).getFileName());
+ System.out.println(" " + CERT_DIR_FROM_ROOT +
+ Paths.get(selfSignedUsingArraysPem).getFileName());
+
+ /* Free native memory */
+ subjectName.free();
+ x509.free();
+ }
+
+ /**
+ * Generate example certificate using generated keys for the certificate
+ * public and private key, to be used in the certificate generation
+ * process.
+ *
+ * Generates and writes certificate out to the following paths in
+ * both PEM and DER format (see variable values above):
+ * selfSignedUsingGeneratedKeysDer (DER format)
+ * selfSignedUsingGeneratedKeysPem (PEM format)
+ *
+ * @throws WolfSSLException if error occurs during certificate generation
+ * process.
+ * @throws WolfSSLJNIException if native JNI error occurs
+ * @throws IOException on error writing to output file locations
+ */
+ public void generateSelfSignedUsingGeneratedKeys()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException, NoSuchAlgorithmException {
+
+ System.out.print("\nGenerating self-signed cert with generated keys");
+
+ /* Create new certificate object */
+ WolfSSLCertificate x509 = new WolfSSLCertificate();
+
+ /* Set notBefore/notAfter validity dates */
+ Instant now = Instant.now();
+ final Date notBefore = Date.from(now);
+ final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
+ x509.setNotBefore(notBefore);
+ x509.setNotAfter(notAfter);
+
+ /* Set serial number */
+ x509.setSerialNumber(BigInteger.valueOf(12345));
+
+ /* Set Subject Name */
+ WolfSSLX509Name subjectName = generateTestSubjectName();
+ x509.setSubjectName(subjectName);
+
+ /* Not setting Issuer, since generating self-signed cert */
+
+ /* Set Public Key from generated java.security.PublicKey */
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ kpg.initialize(2048);
+ KeyPair keyPair = kpg.generateKeyPair();
+ PublicKey pubKey = keyPair.getPublic();
+ x509.setPublicKey(pubKey);
+
+ /* Add Extensions */
+ x509.addExtension(WolfSSL.NID_key_usage, test_KEY_USAGE, false);
+ x509.addExtension(WolfSSL.NID_ext_key_usage, test_EXT_KEY_USAGE, false);
+ x509.addExtension(WolfSSL.NID_subject_alt_name, test_ALT_NAME, false);
+ x509.addExtension(WolfSSL.NID_basic_constraints, true, true);
+
+ /* Sign certificate, self-signed with java.security.PrivateKey */
+ PrivateKey privKey = keyPair.getPrivate();
+ x509.signCert(privKey, "SHA256");
+
+ /* Output to DER and PEM files */
+ byte[] derCert = x509.getDer();
+ byte[] pemCert = x509.getPem();
+
+ /* Write out generated certs to files */
+ writeFile(selfSignedUsingGeneratedKeysDer, derCert);
+ writeFile(selfSignedUsingGeneratedKeysPem, pemCert);
+
+ /* Test converting to X509Certificate */
+ X509Certificate tmpX509 = x509.getX509Certificate();
+
+ System.out.println("... ");
+ System.out.println(" " + CERT_DIR_FROM_ROOT +
+ Paths.get(selfSignedUsingGeneratedKeysDer).getFileName());
+ System.out.println(" " + CERT_DIR_FROM_ROOT +
+ Paths.get(selfSignedUsingGeneratedKeysPem).getFileName());
+
+ /* Free native memory */
+ subjectName.free();
+ x509.free();
+ }
+
+ /**
+ * -----------------------------------------------------------------------
+ * Below are examples of CA-signed certificate generation
+ * -----------------------------------------------------------------------
+ */
+
+ /**
+ * Generate example CA-signed certificate using the following files as
+ * input to the certificate generation process:
+ *
+ * caCertPem - Existing CA certificate in PEM format
+ * clientKeyPubDer - Existing client public key in DER format
+ * clientKeyDer - Existing client private key in DER format
+ *
+ * Generates and writes certificate out to the following paths in
+ * both PEM and DER format (see variable values above):
+ * caSignedUsingFilesDer (DER format)
+ * caSignedUsingFilesPem (PEM format)
+ *
+ * @throws WolfSSLException if error occurs during certificate generation
+ * process.
+ * @throws WolfSSLJNIException if native JNI error occurs
+ * @throws IOException on error writing to output file locations
+ */
+ public void generateCASignedUsingFiles()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException {
+
+ System.out.print("\nGenerating CA-signed cert using files");
+
+ /* Create new certificate object */
+ WolfSSLCertificate x509 = new WolfSSLCertificate();
+
+ /* Set notBefore/notAfter validity dates */
+ Instant now = Instant.now();
+ final Date notBefore = Date.from(now);
+ final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
+ x509.setNotBefore(notBefore);
+ x509.setNotAfter(notAfter);
+
+ /* Set serial number */
+ x509.setSerialNumber(BigInteger.valueOf(12345));
+
+ /* Set Subject Name */
+ WolfSSLX509Name subjectName = generateTestSubjectName();
+ x509.setSubjectName(subjectName);
+
+ /* Set Issuer Name from existing cert file wrapped in
+ * WolfSSLCertificate object */
+ WolfSSLCertificate issuer = new WolfSSLCertificate(caCertPem,
+ WolfSSL.SSL_FILETYPE_PEM);
+ x509.setIssuerName(issuer);
+
+ /* Set Public Key from existing public key DER file */
+ x509.setPublicKey(clientKeyPubDer, WolfSSL.RSAk,
+ WolfSSL.SSL_FILETYPE_ASN1);
+
+ /* Add Extensions */
+ x509.addExtension(WolfSSL.NID_key_usage, test_KEY_USAGE, false);
+ x509.addExtension(WolfSSL.NID_ext_key_usage, test_EXT_KEY_USAGE, false);
+ x509.addExtension(WolfSSL.NID_subject_alt_name, test_ALT_NAME, false);
+ x509.addExtension(WolfSSL.NID_basic_constraints, true, true);
+
+ /* Sign certificate, CA-signed using existing CA key DER */
+ x509.signCert(caKeyDer, WolfSSL.RSAk,
+ WolfSSL.SSL_FILETYPE_ASN1, "SHA256");
+
+ /* Output to DER and PEM files */
+ byte[] derCert = x509.getDer();
+ byte[] pemCert = x509.getPem();
+
+ /* Write out generated certs to files */
+ writeFile(caSignedUsingFilesDer, derCert);
+ writeFile(caSignedUsingFilesPem, pemCert);
+
+ /* Test converting to X509Certificate */
+ X509Certificate tmpX509 = x509.getX509Certificate();
+
+ System.out.println("... ");
+ System.out.println(" " + CERT_DIR_FROM_ROOT +
+ Paths.get(caSignedUsingFilesDer).getFileName());
+ System.out.println(" " + CERT_DIR_FROM_ROOT +
+ Paths.get(caSignedUsingFilesPem).getFileName());
+
+ /* Free native memory */
+ subjectName.free();
+ x509.free();
+ }
+
+ /**
+ * Generate example CA-signed certificate using the following files in
+ * array format as input to the certificate generation process:
+ *
+ * caCertPem - Existing CA certificate in PEM format
+ * clientKeyPubDer - Existing client public key in DER format
+ * clientKeyDer - Existing client private key in DER format
+ *
+ * Generates and writes certificate out to the following paths in
+ * both PEM and DER format (see variable values above):
+ * caSignedUsingArraysDer (DER format)
+ * caSignedUsingArraysPem (PEM format)
+ *
+ * @throws WolfSSLException if error occurs during certificate generation
+ * process.
+ * @throws WolfSSLJNIException if native JNI error occurs
+ * @throws IOException on error writing to output file locations
+ */
+ public void generateCASignedUsingArrays()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException {
+
+ System.out.print("\nGenerating CA-signed cert using arrays");
+
+ /* Create new certificate object */
+ WolfSSLCertificate x509 = new WolfSSLCertificate();
+
+ /* Set notBefore/notAfter validity dates */
+ Instant now = Instant.now();
+ final Date notBefore = Date.from(now);
+ final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
+ x509.setNotBefore(notBefore);
+ x509.setNotAfter(notAfter);
+
+ /* Set serial number */
+ x509.setSerialNumber(BigInteger.valueOf(12345));
+
+ /* Set Subject Name */
+ WolfSSLX509Name subjectName = generateTestSubjectName();
+ x509.setSubjectName(subjectName);
+
+ /* Set Issuer Name from existing cert file ready into a byte array and
+ * wrapped in WolfSSLCertificate object */
+ WolfSSLCertificate issuer = new WolfSSLCertificate(
+ Files.readAllBytes(Paths.get(caCertPem)),
+ WolfSSL.SSL_FILETYPE_PEM);
+ x509.setIssuerName(issuer);
+
+ /* Set Public Key from existing public key DER file */
+ byte[] pubKey = Files.readAllBytes(Paths.get(clientKeyPubDer));
+ x509.setPublicKey(pubKey, WolfSSL.RSAk, WolfSSL.SSL_FILETYPE_ASN1);
+
+ /* Add Extensions */
+ x509.addExtension(WolfSSL.NID_key_usage, test_KEY_USAGE, false);
+ x509.addExtension(WolfSSL.NID_ext_key_usage, test_EXT_KEY_USAGE, false);
+ x509.addExtension(WolfSSL.NID_subject_alt_name, test_ALT_NAME, false);
+ x509.addExtension(WolfSSL.NID_basic_constraints, true, true);
+
+ /* Sign certificate, self-signed using existing client key DER */
+ byte[] privKey = Files.readAllBytes(Paths.get(caKeyDer));
+ x509.signCert(privKey, WolfSSL.RSAk,
+ WolfSSL.SSL_FILETYPE_ASN1, "SHA256");
+
+ /* Output to DER and PEM files */
+ byte[] derCert = x509.getDer();
+ byte[] pemCert = x509.getPem();
+
+ /* Write out generated certs to files */
+ writeFile(caSignedUsingArraysDer, derCert);
+ writeFile(caSignedUsingArraysPem, pemCert);
+
+ /* Test converting to X509Certificate */
+ X509Certificate tmpX509 = x509.getX509Certificate();
+
+ System.out.println("... ");
+ System.out.println(" " + CERT_DIR_FROM_ROOT +
+ Paths.get(caSignedUsingArraysDer).getFileName());
+ System.out.println(" " + CERT_DIR_FROM_ROOT +
+ Paths.get(caSignedUsingArraysPem).getFileName());
+
+ /* Free native memory */
+ subjectName.free();
+ x509.free();
+ }
+
+ /**
+ * Generate example CA-signed certificate using generated keys for the
+ * certificate public and private key, to be used in the certificate
+ * generation process.
+ *
+ * Generates and writes certificate out to the following paths in
+ * both PEM and DER format (see variable values above):
+ * caSignedUsingGeneratedKeysDer (DER format)
+ * caSignedUsingGeneratedKeysPem (PEM format)
+ *
+ * @throws WolfSSLException if error occurs during certificate generation
+ * process.
+ * @throws WolfSSLJNIException if native JNI error occurs
+ * @throws IOException on error writing to output file locations
+ */
+ public void generateCASignedUsingGeneratedKeys()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException, NoSuchAlgorithmException,
+ InvalidKeySpecException {
+
+ System.out.print("\nGenerating CA-signed cert with generated keys");
+
+ /* Create new certificate object */
+ WolfSSLCertificate x509 = new WolfSSLCertificate();
+
+ /* Set notBefore/notAfter validity dates */
+ Instant now = Instant.now();
+ final Date notBefore = Date.from(now);
+ final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
+ x509.setNotBefore(notBefore);
+ x509.setNotAfter(notAfter);
+
+ /* Set serial number */
+ x509.setSerialNumber(BigInteger.valueOf(12345));
+
+ /* Set Subject Name */
+ WolfSSLX509Name subjectName = generateTestSubjectName();
+ x509.setSubjectName(subjectName);
+
+ /* Set Issuer Name from existing cert file wrapped in
+ * WolfSSLCertificate object */
+ WolfSSLCertificate issuer = new WolfSSLCertificate(caCertPem,
+ WolfSSL.SSL_FILETYPE_PEM);
+ X509Certificate issuerX509 = issuer.getX509Certificate();
+ x509.setIssuerName(issuerX509);
+
+ /* Set Public Key from generated java.security.PublicKey */
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ kpg.initialize(2048);
+ KeyPair keyPair = kpg.generateKeyPair();
+ PublicKey pubKey = keyPair.getPublic();
+ x509.setPublicKey(pubKey);
+
+ /* Add Extensions */
+ x509.addExtension(WolfSSL.NID_key_usage, test_KEY_USAGE, false);
+ x509.addExtension(WolfSSL.NID_ext_key_usage, test_EXT_KEY_USAGE, false);
+ x509.addExtension(WolfSSL.NID_subject_alt_name, test_ALT_NAME, false);
+ x509.addExtension(WolfSSL.NID_basic_constraints, true, true);
+
+ /* Sign certificate, using CA's private key */
+ byte[] privBytes = Files.readAllBytes(Paths.get(caKeyPkcs8Der));
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privBytes);
+ RSAPrivateKey rsaPriv = (RSAPrivateKey)kf.generatePrivate(spec);
+ x509.signCert((PrivateKey)rsaPriv, "SHA256");
+
+ /* Output to DER and PEM files */
+ byte[] derCert = x509.getDer();
+ byte[] pemCert = x509.getPem();
+
+ /* Write out generated certs to files */
+ writeFile(caSignedUsingGeneratedKeysDer, derCert);
+ writeFile(caSignedUsingGeneratedKeysPem, pemCert);
+
+ /* Test converting to X509Certificate */
+ X509Certificate tmpX509 = x509.getX509Certificate();
+
+ System.out.println("... ");
+ System.out.println(" " + CERT_DIR_FROM_ROOT +
+ Paths.get(caSignedUsingGeneratedKeysDer).getFileName());
+ System.out.println(" " + CERT_DIR_FROM_ROOT +
+ Paths.get(caSignedUsingGeneratedKeysPem).getFileName());
+
+ /* Free native memory */
+ subjectName.free();
+ x509.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 X509v3 Certificate Generation Example");
+
+ /* Generate self-signed example certificates */
+ generateSelfSignedUsingFiles();
+ generateSelfSignedUsingArrays();
+ generateSelfSignedUsingGeneratedKeys();
+
+ /* Generate CA-signed example certificates */
+ generateCASignedUsingFiles();
+ generateCASignedUsingArrays();
+ generateCASignedUsingGeneratedKeys();
+
+ } catch (WolfSSLException | WolfSSLJNIException |
+ IOException | CertificateException |
+ NoSuchAlgorithmException | InvalidKeySpecException e) {
+ e.printStackTrace();
+
+ /* exit with error */
+ System.exit(1);
+ }
+
+ } /* end run() */
+
+ public static void main(String[] args) {
+ new X509v3CertificateGeneration().run(args);
+ }
+
+} /* end X509v3CertificateGeneration */
+
diff --git a/examples/X509v3CertificateGeneration.sh b/examples/X509v3CertificateGeneration.sh
new file mode 100755
index 0000000..dfeb0af
--- /dev/null
+++ b/examples/X509v3CertificateGeneration.sh
@@ -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 X509v3CertificateGeneration $@
+
+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 certs with openssl...\n"
+
+printf "Testing each can be opened with openssl x509 -text\n"
+
+# Test reading each DER cert
+CERT_FILES="../certs/generated/*.der"
+for f in $CERT_FILES
+do
+ $OPENSSL x509 -inform DER -in $f -text -noout > /dev/null
+ if [ $? != 0 ]; then
+ printf "File not readable with openssl x509: $f\n"
+ exit -1
+ fi
+done
+
+# Test reading each PEM cert
+CERT_FILES="../certs/generated/*.pem"
+for f in $CERT_FILES
+do
+ $OPENSSL x509 -inform PEM -in $f -text -noout > /dev/null
+ if [ $? != 0 ]; then
+ printf "File not readable with openssl x509: $f\n"
+ exit -1
+ fi
+done
+
+printf "Verification successful\n"
diff --git a/examples/certs/ca-cert.pem b/examples/certs/ca-cert.pem
index 2c7fc17..58688a0 100644
--- a/examples/certs/ca-cert.pem
+++ b/examples/certs/ca-cert.pem
@@ -2,12 +2,12 @@ Certificate:
Data:
Version: 3 (0x2)
Serial Number:
- 26:8c:93:f9:f9:f4:1e:b3:01:72:94:55:67:6d:e2:f8:3d:da:e9:f4
+ 2c:80:ce:db:47:9d:07:66:92:3d:68:d7:ca:ac:90:4f:ca:69:41:4b
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Validity
- Not Before: Feb 15 12:50:24 2022 GMT
- Not After : Nov 11 12:50:24 2024 GMT
+ Not Before: Dec 16 21:17:49 2022 GMT
+ Not After : Sep 11 21:17:49 2025 GMT
Subject: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
@@ -38,7 +38,7 @@ Certificate:
X509v3 Authority Key Identifier:
keyid:27:8E:67:11:74:C3:26:1D:3F:ED:33:63:B3:A4:D8:1D:30:E5:E8:D5
DirName:/C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
- serial:26:8C:93:F9:F9:F4:1E:B3:01:72:94:55:67:6D:E2:F8:3D:DA:E9:F4
+ serial:2C:80:CE:DB:47:9D:07:66:92:3D:68:D7:CA:AC:90:4F:CA:69:41:4B
X509v3 Basic Constraints:
CA:TRUE
@@ -47,27 +47,27 @@ Certificate:
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Signature Algorithm: sha256WithRSAEncryption
- 62:e4:1b:28:3c:9d:d2:60:a9:55:be:6a:f6:20:f2:da:e8:a1:
- 1a:97:b1:90:77:82:ed:c7:77:29:53:33:18:10:62:e0:bd:93:
- 1b:d2:d6:a1:80:43:1d:64:f1:42:92:ec:b7:b8:f0:6b:da:59:
- 83:f4:b8:87:e6:fc:70:21:ea:62:32:70:68:14:0e:dc:b4:f1:
- 66:e2:6e:ab:d2:72:6f:da:df:71:f6:3d:27:97:7d:be:e1:d1:
- ac:16:ad:d7:4f:aa:9d:0c:1e:6e:a9:5e:7d:57:5b:3c:c7:6d:
- d2:f2:5c:c3:dc:3d:36:99:8e:ab:c0:7f:13:a5:f4:67:8b:e2:
- a6:51:31:f1:03:91:00:a8:c4:c5:1d:7f:35:62:b8:1d:a0:a5:
- ab:ec:32:68:ee:f3:ca:48:16:9f:f4:1e:7e:ea:fa:b0:86:15:
- 52:36:6c:4b:58:44:a7:eb:20:78:6e:7e:e8:00:40:ac:98:d8:
- 53:f3:13:4b:b8:98:66:50:63:ed:af:e5:a4:f6:c9:90:1c:84:
- 0a:09:45:2f:a1:e1:37:63:b5:43:8c:a0:2e:7f:c4:d4:e1:ae:
- b7:b9:45:13:f8:70:d5:79:06:4f:82:83:4b:98:d7:56:47:64:
- 9a:6a:6d:8e:7a:9d:ef:83:0f:6b:75:0e:47:22:92:f3:b4:b2:
- 84:61:1f:1c
+ ae:b0:a4:35:8e:8a:1b:a6:eb:b3:a2:57:cf:3a:1f:dc:6e:bc:
+ d2:d0:a6:4a:8f:88:0a:6e:74:d5:d1:7c:d1:44:b1:d4:3b:17:
+ 03:09:5a:46:ed:08:08:cf:f1:fd:20:07:67:c0:97:ec:35:f3:
+ 75:ca:20:61:98:3e:f5:4d:be:e6:9d:75:1e:e4:03:ad:8c:a6:
+ 1e:3d:ec:e4:1a:92:5b:f9:a3:ad:83:ca:4f:cd:aa:38:bb:6e:
+ ae:ad:fa:a7:46:f1:8b:73:ec:09:23:bc:f2:18:e5:b7:92:86:
+ 3e:a4:75:60:c7:3d:0f:3f:83:00:c3:06:08:9c:d1:54:d6:ba:
+ 6d:95:3d:34:a1:be:24:91:cc:20:03:11:5b:72:1c:d4:65:d0:
+ 11:88:75:26:04:26:ef:66:70:e6:3b:38:87:9c:53:71:1b:09:
+ 51:70:50:99:4c:31:0c:62:44:57:30:60:04:fc:12:2c:a3:24:
+ b4:f7:11:d5:0e:b5:21:0b:ed:86:11:67:4d:36:fa:57:a0:59:
+ 55:21:b3:6d:e4:77:5e:ec:7e:f0:09:13:8e:99:98:b2:e1:82:
+ b6:4b:3e:0f:41:a6:0c:cd:49:99:7e:e4:8a:cb:37:ed:53:cf:
+ 86:5d:a9:26:a8:e5:01:25:5a:b4:bc:25:35:f1:fa:5a:5c:ce:
+ d4:b8:9a:2c
-----BEGIN CERTIFICATE-----
-MIIE/zCCA+egAwIBAgIUJoyT+fn0HrMBcpRVZ23i+D3a6fQwDQYJKoZIhvcNAQEL
+MIIE/zCCA+egAwIBAgIULIDO20edB2aSPWjXyqyQT8ppQUswDQYJKoZIhvcNAQEL
BQAwgZQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdC
b3plbWFuMREwDwYDVQQKDAhTYXd0b290aDETMBEGA1UECwwKQ29uc3VsdGluZzEY
MBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdv
-bGZzc2wuY29tMB4XDTIyMDIxNTEyNTAyNFoXDTI0MTExMTEyNTAyNFowgZQxCzAJ
+bGZzc2wuY29tMB4XDTIyMTIxNjIxMTc0OVoXDTI1MDkxMTIxMTc0OVowgZQxCzAJ
BgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMREw
DwYDVQQKDAhTYXd0b290aDETMBEGA1UECwwKQ29uc3VsdGluZzEYMBYGA1UEAwwP
d3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29t
@@ -82,12 +82,12 @@ BgNVHSMEgcwwgcmAFCeOZxF0wyYdP+0zY7Ok2B0w5ejVoYGapIGXMIGUMQswCQYD
VQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjERMA8G
A1UECgwIU2F3dG9vdGgxEzARBgNVBAsMCkNvbnN1bHRpbmcxGDAWBgNVBAMMD3d3
dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbYIU
-JoyT+fn0HrMBcpRVZ23i+D3a6fQwDAYDVR0TBAUwAwEB/zAcBgNVHREEFTATggtl
+LIDO20edB2aSPWjXyqyQT8ppQUswDAYDVR0TBAUwAwEB/zAcBgNVHREEFTATggtl
eGFtcGxlLmNvbYcEfwAAATAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
-DQYJKoZIhvcNAQELBQADggEBAGLkGyg8ndJgqVW+avYg8trooRqXsZB3gu3HdylT
-MxgQYuC9kxvS1qGAQx1k8UKS7Le48GvaWYP0uIfm/HAh6mIycGgUDty08WbibqvS
-cm/a33H2PSeXfb7h0awWrddPqp0MHm6pXn1XWzzHbdLyXMPcPTaZjqvAfxOl9GeL
-4qZRMfEDkQCoxMUdfzViuB2gpavsMmju88pIFp/0Hn7q+rCGFVI2bEtYRKfrIHhu
-fugAQKyY2FPzE0u4mGZQY+2v5aT2yZAchAoJRS+h4TdjtUOMoC5/xNThrre5RRP4
-cNV5Bk+Cg0uY11ZHZJpqbY56ne+DD2t1DkcikvO0soRhHxw=
+DQYJKoZIhvcNAQELBQADggEBAK6wpDWOihum67OiV886H9xuvNLQpkqPiApudNXR
+fNFEsdQ7FwMJWkbtCAjP8f0gB2fAl+w183XKIGGYPvVNvuaddR7kA62Mph497OQa
+klv5o62Dyk/Nqji7bq6t+qdG8Ytz7AkjvPIY5beShj6kdWDHPQ8/gwDDBgic0VTW
+um2VPTShviSRzCADEVtyHNRl0BGIdSYEJu9mcOY7OIecU3EbCVFwUJlMMQxiRFcw
+YAT8EiyjJLT3EdUOtSEL7YYRZ002+legWVUhs23kd17sfvAJE46ZmLLhgrZLPg9B
+pgzNSZl+5IrLN+1Tz4ZdqSao5QElWrS8JTXx+lpcztS4miw=
-----END CERTIFICATE-----
diff --git a/examples/certs/ca-ecc-cert.pem b/examples/certs/ca-ecc-cert.pem
index 1d0148d..e4e4c7c 100644
--- a/examples/certs/ca-ecc-cert.pem
+++ b/examples/certs/ca-ecc-cert.pem
@@ -2,12 +2,12 @@ Certificate:
Data:
Version: 3 (0x2)
Serial Number:
- 29:bf:2b:cd:bf:55:54:49:85:b3:69:4e:e1:85:37:79:1e:81:f9:c2
+ 65:67:42:4c:06:e7:e4:c3:68:01:a9:94:a9:07:e6:fe:bd:2c:d6:3d
Signature Algorithm: ecdsa-with-SHA256
Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Development, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Validity
- Not Before: Feb 15 12:50:24 2022 GMT
- Not After : Nov 11 12:50:24 2024 GMT
+ Not Before: Dec 16 21:17:49 2022 GMT
+ Not After : Sep 11 21:17:49 2025 GMT
Subject: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Development, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
@@ -31,16 +31,16 @@ Certificate:
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
Signature Algorithm: ecdsa-with-SHA256
- 30:44:02:20:78:ed:4c:1c:a7:2d:b3:35:0b:1d:46:a3:37:31:
- 0b:8a:05:39:c8:28:31:58:35:f1:98:f7:4b:72:c0:4f:e6:7f:
- 02:20:02:f2:09:2b:3a:e1:36:92:bf:58:6a:03:12:2d:79:e6:
- bd:06:45:61:b9:0e:39:e1:9c:f0:a8:2e:0b:1e:8c:b2
+ 30:46:02:21:00:b0:12:16:03:26:79:d4:6b:94:d9:7e:ca:e1:
+ 2d:24:64:ef:11:6e:f2:12:81:e4:ce:1d:77:7d:ca:5c:47:50:
+ 62:02:21:00:80:bf:46:3c:5d:d8:e5:ab:47:ce:a2:19:bd:21:
+ de:85:6f:ab:c9:8f:01:f3:ab:1b:b9:e1:53:d6:24:77:a6:4d
-----BEGIN CERTIFICATE-----
-MIIClDCCAjugAwIBAgIUKb8rzb9VVEmFs2lO4YU3eR6B+cIwCgYIKoZIzj0EAwIw
+MIICljCCAjugAwIBAgIUZWdCTAbn5MNoAamUqQfm/r0s1j0wCgYIKoZIzj0EAwIw
gZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdT
ZWF0dGxlMRAwDgYDVQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtEZXZlbG9wbWVudDEY
MBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdv
-bGZzc2wuY29tMB4XDTIyMDIxNTEyNTAyNFoXDTI0MTExMTEyNTAyNFowgZcxCzAJ
+bGZzc2wuY29tMB4XDTIyMTIxNjIxMTc0OVoXDTI1MDkxMTIxMTc0OVowgZcxCzAJ
BgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxl
MRAwDgYDVQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtEZXZlbG9wbWVudDEYMBYGA1UE
AwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wu
@@ -48,6 +48,6 @@ Y29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAtPZbtYBjkXIuZAx5cBM456t
KTiYuhDW6QkqgKkuFyq5ir8zg0bjlQvkd0C1O0NFMw9hU3w3RMHL/IDK6EPqp6Nj
MGEwHQYDVR0OBBYEFFaOmsPwQt4YuUVVbvmTz+rD86UhMB8GA1UdIwQYMBaAFFaO
msPwQt4YuUVVbvmTz+rD86UhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
-AgGGMAoGCCqGSM49BAMCA0cAMEQCIHjtTBynLbM1Cx1GozcxC4oFOcgoMVg18Zj3
-S3LAT+Z/AiAC8gkrOuE2kr9YagMSLXnmvQZFYbkOOeGc8KguCx6Msg==
+AgGGMAoGCCqGSM49BAMCA0kAMEYCIQCwEhYDJnnUa5TZfsrhLSRk7xFu8hKB5M4d
+d33KXEdQYgIhAIC/Rjxd2OWrR86iGb0h3oVvq8mPAfOrG7nhU9Ykd6ZN
-----END CERTIFICATE-----
diff --git a/examples/certs/ca-key.der b/examples/certs/ca-key.der
new file mode 100644
index 0000000..14456f3
Binary files /dev/null and b/examples/certs/ca-key.der differ
diff --git a/examples/certs/ca-keyPkcs8.der b/examples/certs/ca-keyPkcs8.der
new file mode 100644
index 0000000..58ac8d4
Binary files /dev/null and b/examples/certs/ca-keyPkcs8.der differ
diff --git a/examples/certs/client-cert.der b/examples/certs/client-cert.der
index 321f5c1..aa7e268 100644
Binary files a/examples/certs/client-cert.der and b/examples/certs/client-cert.der differ
diff --git a/examples/certs/client-cert.pem b/examples/certs/client-cert.pem
index 26c7384..4bf36d3 100644
--- a/examples/certs/client-cert.pem
+++ b/examples/certs/client-cert.pem
@@ -2,12 +2,12 @@ Certificate:
Data:
Version: 3 (0x2)
Serial Number:
- 01:1a:eb:56:ab:dc:8b:f3:a6:1e:f4:93:60:89:b7:05:07:29:01:2c
+ 73:fb:54:d6:03:7d:4c:07:84:e2:00:11:8c:dd:90:dc:48:8d:ea:53
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_2048, OU = Programming-2048, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Validity
- Not Before: Feb 15 12:50:24 2022 GMT
- Not After : Nov 11 12:50:24 2024 GMT
+ Not Before: Dec 16 21:17:49 2022 GMT
+ Not After : Sep 11 21:17:49 2025 GMT
Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_2048, OU = Programming-2048, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
@@ -38,7 +38,7 @@ Certificate:
X509v3 Authority Key Identifier:
keyid:33:D8:45:66:D7:68:87:18:7E:54:0D:70:27:91:C7:26:D7:85:65:C0
DirName:/C=US/ST=Montana/L=Bozeman/O=wolfSSL_2048/OU=Programming-2048/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
- serial:01:1A:EB:56:AB:DC:8B:F3:A6:1E:F4:93:60:89:B7:05:07:29:01:2C
+ serial:73:FB:54:D6:03:7D:4C:07:84:E2:00:11:8C:DD:90:DC:48:8D:EA:53
X509v3 Basic Constraints:
CA:TRUE
@@ -47,28 +47,28 @@ Certificate:
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Signature Algorithm: sha256WithRSAEncryption
- 64:6d:a6:4a:a8:9f:a7:e9:75:2c:f3:85:3d:3e:af:38:fb:6c:
- c7:eb:c7:d0:2b:a2:45:b5:65:be:d0:13:2c:f7:a3:c1:eb:3c:
- b1:f8:b8:3d:63:8f:ca:08:4e:65:1d:2c:ce:34:6e:35:96:87:
- 93:30:5d:aa:c8:e9:a0:9c:9b:84:78:3a:52:a1:33:48:6e:84:
- 66:71:9c:cf:d1:c7:7b:02:4c:e1:49:7c:69:47:fc:b7:01:f9:
- a0:39:3b:ab:b9:c6:d9:ca:27:85:f0:5c:b6:a4:e6:dc:f2:52:
- fe:44:00:b6:f0:47:f2:6f:3f:d5:0f:ff:31:93:53:88:8c:c7:
- fb:56:10:4b:3b:43:e6:8a:9c:b7:b4:9a:dd:5c:e3:cd:9c:bd:
- a7:0c:c1:d9:96:f0:93:f3:ab:bd:d2:1e:77:8a:42:cd:0f:fe:
- 48:da:57:34:61:46:a3:89:2e:31:d2:4a:d4:43:2f:56:85:44:
- 75:ca:6b:36:e2:e8:3a:b2:95:95:3a:28:90:8d:c0:23:fb:3c:
- d2:1a:73:6b:ef:fd:d6:1b:eb:6d:67:2a:e1:eb:2a:83:22:ad:
- e3:95:19:e5:93:ee:14:dc:b5:7d:e7:cf:89:8c:d7:8f:d2:3f:
- 68:7e:a9:74:7c:1b:38:65:f9:28:4d:ff:50:c8:ee:51:3a:8f:
- 1d:9e:55:5e
+ 36:cb:bc:c5:52:9a:66:cd:91:4d:8f:27:9f:b3:64:80:0e:64:
+ b4:cb:1a:cd:75:9e:82:7c:55:67:d8:9f:90:a3:34:96:99:43:
+ f7:49:53:a2:58:85:a0:b3:83:4f:af:b8:15:8a:88:1e:f3:60:
+ f4:7c:94:b5:58:68:f1:2a:13:80:34:c2:6f:a5:f8:7e:76:16:
+ 81:4f:36:8b:c3:59:bd:51:dd:60:87:d7:1d:96:44:69:07:3c:
+ 8f:28:56:b1:11:5c:4e:81:3f:57:25:fd:65:dd:07:cf:17:0a:
+ 01:7e:4e:3f:8e:73:db:fe:f4:f2:c5:ff:a3:76:a8:74:46:2e:
+ 47:0d:b0:ed:0a:c0:c5:0a:65:d3:dc:62:b2:e0:1e:8e:bd:f3:
+ bd:af:af:66:84:36:92:e2:3b:80:d0:57:a6:41:a3:62:d1:a6:
+ 6d:14:6c:cd:82:b1:c1:c1:35:55:ae:59:49:a8:26:52:bd:ef:
+ 1b:2c:1f:9d:39:04:d2:82:a0:6b:39:71:59:33:82:ba:55:6c:
+ 97:f2:1b:5b:e0:4d:e2:cf:89:e7:26:b8:2c:6c:9f:83:d6:ed:
+ 4e:2f:75:a9:30:4e:01:95:0d:4f:83:5e:c8:af:7f:67:ea:53:
+ bf:ca:9b:1f:d4:ff:36:97:02:71:8e:33:de:e2:58:27:aa:70:
+ 0c:5b:de:0e
-----BEGIN CERTIFICATE-----
-MIIFHTCCBAWgAwIBAgIUARrrVqvci/OmHvSTYIm3BQcpASwwDQYJKoZIhvcNAQEL
+MIIFHTCCBAWgAwIBAgIUc/tU1gN9TAeE4gARjN2Q3EiN6lMwDQYJKoZIhvcNAQEL
BQAwgZ4xCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdC
b3plbWFuMRUwEwYDVQQKDAx3b2xmU1NMXzIwNDgxGTAXBgNVBAsMEFByb2dyYW1t
aW5nLTIwNDgxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJ
-ARYQaW5mb0B3b2xmc3NsLmNvbTAeFw0yMjAyMTUxMjUwMjRaFw0yNDExMTExMjUw
-MjRaMIGeMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwH
+ARYQaW5mb0B3b2xmc3NsLmNvbTAeFw0yMjEyMTYyMTE3NDlaFw0yNTA5MTEyMTE3
+NDlaMIGeMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwH
Qm96ZW1hbjEVMBMGA1UECgwMd29sZlNTTF8yMDQ4MRkwFwYDVQQLDBBQcm9ncmFt
bWluZy0yMDQ4MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0B
CQEWEGluZm9Ad29sZnNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
@@ -82,13 +82,13 @@ Ztdohxh+VA1wJ5HHJteFZcAwgd4GA1UdIwSB1jCB04AUM9hFZtdohxh+VA1wJ5HH
JteFZcChgaSkgaEwgZ4xCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAw
DgYDVQQHDAdCb3plbWFuMRUwEwYDVQQKDAx3b2xmU1NMXzIwNDgxGTAXBgNVBAsM
EFByb2dyYW1taW5nLTIwNDgxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0G
-CSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbYIUARrrVqvci/OmHvSTYIm3BQcp
-ASwwDAYDVR0TBAUwAwEB/zAcBgNVHREEFTATggtleGFtcGxlLmNvbYcEfwAAATAd
+CSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbYIUc/tU1gN9TAeE4gARjN2Q3EiN
+6lMwDAYDVR0TBAUwAwEB/zAcBgNVHREEFTATggtleGFtcGxlLmNvbYcEfwAAATAd
BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEB
-AGRtpkqon6fpdSzzhT0+rzj7bMfrx9ArokW1Zb7QEyz3o8HrPLH4uD1jj8oITmUd
-LM40bjWWh5MwXarI6aCcm4R4OlKhM0huhGZxnM/Rx3sCTOFJfGlH/LcB+aA5O6u5
-xtnKJ4XwXLak5tzyUv5EALbwR/JvP9UP/zGTU4iMx/tWEEs7Q+aKnLe0mt1c482c
-vacMwdmW8JPzq73SHneKQs0P/kjaVzRhRqOJLjHSStRDL1aFRHXKazbi6DqylZU6
-KJCNwCP7PNIac2vv/dYb621nKuHrKoMireOVGeWT7hTctX3nz4mM14/SP2h+qXR8
-Gzhl+ShN/1DI7lE6jx2eVV4=
+ADbLvMVSmmbNkU2PJ5+zZIAOZLTLGs11noJ8VWfYn5CjNJaZQ/dJU6JYhaCzg0+v
+uBWKiB7zYPR8lLVYaPEqE4A0wm+l+H52FoFPNovDWb1R3WCH1x2WRGkHPI8oVrER
+XE6BP1cl/WXdB88XCgF+Tj+Oc9v+9PLF/6N2qHRGLkcNsO0KwMUKZdPcYrLgHo69
+872vr2aENpLiO4DQV6ZBo2LRpm0UbM2CscHBNVWuWUmoJlK97xssH505BNKCoGs5
+cVkzgrpVbJfyG1vgTeLPiecmuCxsn4PW7U4vdakwTgGVDU+DXsivf2fqU7/Kmx/U
+/zaXAnGOM97iWCeqcAxb3g4=
-----END CERTIFICATE-----
diff --git a/examples/certs/client-key.der b/examples/certs/client-key.der
new file mode 100644
index 0000000..94dc253
Binary files /dev/null and b/examples/certs/client-key.der differ
diff --git a/examples/certs/client-keyPub.der b/examples/certs/client-keyPub.der
new file mode 100644
index 0000000..b27f0e9
Binary files /dev/null and b/examples/certs/client-keyPub.der differ
diff --git a/examples/certs/crl/cliCrl.pem b/examples/certs/crl/cliCrl.pem
index 603da9a..10fe581 100644
--- a/examples/certs/crl/cliCrl.pem
+++ b/examples/certs/crl/cliCrl.pem
@@ -2,41 +2,41 @@ Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_2048, OU = Programming-2048, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
- Last Update: Feb 15 12:50:27 2022 GMT
- Next Update: Nov 11 12:50:27 2024 GMT
+ Last Update: Dec 16 21:17:50 2022 GMT
+ Next Update: Sep 11 21:17:50 2025 GMT
CRL extensions:
X509v3 CRL Number:
6
Revoked Certificates:
Serial Number: 02
- Revocation Date: Feb 15 12:50:27 2022 GMT
+ Revocation Date: Dec 16 21:17:50 2022 GMT
Signature Algorithm: sha256WithRSAEncryption
- 7e:92:50:e4:30:78:22:ed:6f:79:a5:cb:65:3c:de:7a:83:88:
- 1e:66:8a:e5:2e:42:c6:9f:66:31:94:22:89:30:18:a2:b4:28:
- 76:b1:bc:8b:4a:0d:aa:ee:92:b6:4e:b5:11:87:6b:57:18:4d:
- fd:3c:b1:75:d7:b3:16:0e:7a:42:76:c5:b8:7c:22:15:11:c0:
- 9b:0d:a6:fe:42:86:ef:cb:79:60:4d:35:20:4c:a3:a2:37:07:
- de:dd:94:fe:49:86:ae:7c:86:71:e2:86:9a:2b:e2:a2:80:6c:
- 96:3c:8b:13:4f:f6:52:63:6d:1c:7c:af:3f:22:c1:53:97:6b:
- d0:2f:84:88:68:23:e1:8c:2d:bd:57:e3:c7:eb:6f:20:13:a7:
- 13:86:2f:2e:d5:3b:87:bb:08:3b:24:cb:dd:10:17:48:d9:97:
- 67:28:6e:40:6a:70:45:04:6f:93:52:77:a3:21:7e:58:29:95:
- 96:a6:3f:a2:73:83:2f:3e:d8:85:0a:f4:7d:39:04:9b:5d:cb:
- 7e:d4:6a:33:63:b4:67:6f:b8:e3:3a:6a:7b:57:ed:f6:bd:98:
- 11:fb:f1:0e:c8:29:73:fd:dd:55:93:d4:00:05:5c:be:d6:e7:
- 24:ec:9d:d0:41:d3:1c:dc:4b:de:df:64:e1:00:39:dc:7d:04:
- 75:fd:94:7c
+ bf:d3:f7:5b:70:94:5a:11:50:b2:7d:7b:f9:c8:0f:aa:1b:82:
+ f9:24:5f:79:a6:ab:9d:71:53:83:a2:29:93:a4:91:9d:70:0e:
+ b7:b7:e2:67:b8:ee:1c:fb:81:be:f7:e6:a7:d7:c0:df:5d:d3:
+ 4b:df:50:1c:08:c3:95:20:bd:6c:0e:f8:c9:70:66:cd:42:19:
+ d8:a5:75:bf:cc:b4:fb:f4:fc:85:58:06:95:07:fd:a5:c2:a8:
+ ac:a3:e9:eb:0c:99:98:f8:62:a8:59:22:d5:72:71:05:8a:ca:
+ 6a:5a:96:c1:a3:29:b2:ea:78:30:1d:8c:c5:17:26:b5:d4:87:
+ 79:c9:f6:51:2e:c9:e9:b5:f4:17:2a:8e:ba:3d:e9:8d:e0:66:
+ 87:7b:8f:36:8c:62:45:7a:07:2b:b2:da:02:ba:27:b9:e6:18:
+ d8:84:5f:4d:8f:cd:03:91:e8:53:c8:10:c8:d9:51:af:3d:e3:
+ 35:25:cd:3e:44:7e:fd:8f:74:46:4a:b9:03:da:41:2b:b1:4d:
+ 4c:39:af:14:fa:9c:4f:54:4c:4b:9f:a8:4a:b6:99:24:95:54:
+ 37:05:ab:45:7b:7b:25:20:d1:99:b1:5e:aa:98:a0:1e:b9:b1:
+ a3:fe:e5:2c:f8:49:d8:94:07:05:79:b5:9b:19:0e:53:c8:b3:
+ ce:60:d0:bc
-----BEGIN X509 CRL-----
MIICDjCB9wIBATANBgkqhkiG9w0BAQsFADCBnjELMAkGA1UEBhMCVVMxEDAOBgNV
BAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xFTATBgNVBAoMDHdvbGZTU0xf
MjA0ODEZMBcGA1UECwwQUHJvZ3JhbW1pbmctMjA0ODEYMBYGA1UEAwwPd3d3Lndv
-bGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tFw0yMjAy
-MTUxMjUwMjdaFw0yNDExMTExMjUwMjdaMBQwEgIBAhcNMjIwMjE1MTI1MDI3WqAO
-MAwwCgYDVR0UBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAH6SUOQweCLtb3mly2U8
-3nqDiB5miuUuQsafZjGUIokwGKK0KHaxvItKDarukrZOtRGHa1cYTf08sXXXsxYO
-ekJ2xbh8IhURwJsNpv5Chu/LeWBNNSBMo6I3B97dlP5Jhq58hnHihpor4qKAbJY8
-ixNP9lJjbRx8rz8iwVOXa9AvhIhoI+GMLb1X48frbyATpxOGLy7VO4e7CDsky90Q
-F0jZl2cobkBqcEUEb5NSd6MhflgplZamP6Jzgy8+2IUK9H05BJtdy37UajNjtGdv
-uOM6antX7fa9mBH78Q7IKXP93VWT1AAFXL7W5yTsndBB0xzcS97fZOEAOdx9BHX9
-lHw=
+bGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tFw0yMjEy
+MTYyMTE3NTBaFw0yNTA5MTEyMTE3NTBaMBQwEgIBAhcNMjIxMjE2MjExNzUwWqAO
+MAwwCgYDVR0UBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAL/T91twlFoRULJ9e/nI
+D6obgvkkX3mmq51xU4OiKZOkkZ1wDre34me47hz7gb735qfXwN9d00vfUBwIw5Ug
+vWwO+MlwZs1CGdildb/MtPv0/IVYBpUH/aXCqKyj6esMmZj4YqhZItVycQWKympa
+lsGjKbLqeDAdjMUXJrXUh3nJ9lEuyem19Bcqjro96Y3gZod7jzaMYkV6Byuy2gK6
+J7nmGNiEX02PzQOR6FPIEMjZUa894zUlzT5Efv2PdEZKuQPaQSuxTUw5rxT6nE9U
+TEufqEq2mSSVVDcFq0V7eyUg0ZmxXqqYoB65saP+5Sz4SdiUBwV5tZsZDlPIs85g
+0Lw=
-----END X509 CRL-----
diff --git a/examples/certs/crl/crl.pem b/examples/certs/crl/crl.pem
index 8f96121..9da22d8 100644
--- a/examples/certs/crl/crl.pem
+++ b/examples/certs/crl/crl.pem
@@ -2,40 +2,40 @@ Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
- Last Update: Feb 15 12:50:27 2022 GMT
- Next Update: Nov 11 12:50:27 2024 GMT
+ Last Update: Dec 16 21:17:50 2022 GMT
+ Next Update: Sep 11 21:17:50 2025 GMT
CRL extensions:
X509v3 CRL Number:
2
Revoked Certificates:
Serial Number: 02
- Revocation Date: Feb 15 12:50:27 2022 GMT
+ Revocation Date: Dec 16 21:17:50 2022 GMT
Signature Algorithm: sha256WithRSAEncryption
- 43:e6:3b:30:0e:32:53:32:a4:08:3c:e5:d5:2e:f1:ce:e9:95:
- ff:ba:d6:fe:2e:59:80:f8:0a:2f:cf:1e:e0:37:fe:ca:cc:33:
- 66:8b:ed:65:50:7d:44:92:d3:5c:52:9a:95:a5:9d:a5:4e:77:
- 8b:b4:7f:59:c8:7a:e0:eb:34:32:ae:a1:03:99:d2:3c:c0:f4:
- 7e:1c:87:4c:6c:5a:ba:0a:95:e8:a1:44:01:7b:8f:3e:a4:e3:
- e8:1e:07:19:f0:09:7a:85:8f:f3:82:62:f8:1e:08:51:a3:60:
- 30:5b:06:c8:a2:b3:ff:aa:28:66:ad:fe:4b:81:49:30:ef:5f:
- 5d:ac:d9:ad:17:9f:2a:b6:22:d6:35:cc:9f:d9:11:26:dd:7a:
- 06:35:d0:d5:c7:41:6c:52:97:8c:aa:82:5a:e5:a8:58:d4:b7:
- 2b:31:84:34:15:bd:08:e4:9e:71:9e:c5:40:f8:02:a3:a0:1e:
- 4f:98:72:2b:eb:9e:8a:4e:01:83:88:e5:cb:6e:3b:52:e3:a9:
- 34:a1:7c:e4:79:2c:d1:e0:0b:74:22:ba:6d:cb:c3:a1:56:f9:
- c9:f4:20:bf:00:49:df:6b:59:49:18:c7:75:27:8e:a1:5a:a6:
- ff:f2:be:34:4a:c9:6d:6e:24:a3:1f:15:7e:34:90:b6:81:bf:
- 15:80:c3:ac
+ 39:44:ff:39:f4:04:45:79:7e:73:e2:42:48:db:85:66:fd:99:
+ 76:94:7c:b5:79:5d:15:71:36:a9:87:f0:73:05:50:08:6b:1c:
+ 6e:de:96:45:31:c3:c0:ba:ba:f5:08:1d:05:4a:52:39:e9:03:
+ ef:59:c8:1d:4a:f2:86:05:99:7b:4b:74:f6:d3:75:8d:b2:57:
+ ba:ac:a7:11:14:d6:6c:71:c4:4c:1c:68:bc:49:78:f0:c9:52:
+ 8a:e7:8b:54:e6:20:58:20:60:66:f5:14:d8:cb:ff:e0:a0:45:
+ bc:b4:81:ad:1d:bc:cf:f8:8e:a8:87:24:55:99:d9:ce:47:f7:
+ 5b:4a:33:6d:db:bf:93:64:1a:a6:46:5f:27:dc:d8:d4:f9:c2:
+ 42:2a:7e:b2:7c:dd:98:77:f5:88:7d:15:25:08:bc:e0:d0:8d:
+ f4:c3:c3:04:41:a4:d1:b1:39:4a:6b:2c:b5:2e:9a:65:43:0d:
+ 0e:73:f4:06:e1:b3:49:34:94:b0:b7:ff:c0:27:c1:b5:ea:06:
+ f7:71:71:97:bb:bc:c7:1a:9f:eb:f6:3d:a5:7b:55:a7:bf:dd:
+ d7:ee:97:b8:9d:dc:cd:e3:06:db:9a:2c:60:bf:70:84:fa:6b:
+ 8d:70:7d:de:e8:b7:ab:b0:38:68:6c:c0:b1:e1:ba:45:e0:d7:
+ 12:3d:71:5b
-----BEGIN X509 CRL-----
MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADCBlDELMAkGA1UEBhMCVVMxEDAOBgNV
BAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNhd3Rvb3Ro
MRMwEQYDVQQLDApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20x
-HzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20XDTIyMDIxNTEyNTAyN1oX
-DTI0MTExMTEyNTAyN1owFDASAgECFw0yMjAyMTUxMjUwMjdaoA4wDDAKBgNVHRQE
-AwIBAjANBgkqhkiG9w0BAQsFAAOCAQEAQ+Y7MA4yUzKkCDzl1S7xzumV/7rW/i5Z
-gPgKL88e4Df+yswzZovtZVB9RJLTXFKalaWdpU53i7R/Wch64Os0Mq6hA5nSPMD0
-fhyHTGxaugqV6KFEAXuPPqTj6B4HGfAJeoWP84Ji+B4IUaNgMFsGyKKz/6ooZq3+
-S4FJMO9fXazZrRefKrYi1jXMn9kRJt16BjXQ1cdBbFKXjKqCWuWoWNS3KzGENBW9
-COSecZ7FQPgCo6AeT5hyK+ueik4Bg4jly247UuOpNKF85Hks0eALdCK6bcvDoVb5
-yfQgvwBJ32tZSRjHdSeOoVqm//K+NErJbW4kox8VfjSQtoG/FYDDrA==
+HzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20XDTIyMTIxNjIxMTc1MFoX
+DTI1MDkxMTIxMTc1MFowFDASAgECFw0yMjEyMTYyMTE3NTBaoA4wDDAKBgNVHRQE
+AwIBAjANBgkqhkiG9w0BAQsFAAOCAQEAOUT/OfQERXl+c+JCSNuFZv2ZdpR8tXld
+FXE2qYfwcwVQCGscbt6WRTHDwLq69QgdBUpSOekD71nIHUryhgWZe0t09tN1jbJX
+uqynERTWbHHETBxovEl48MlSiueLVOYgWCBgZvUU2Mv/4KBFvLSBrR28z/iOqIck
+VZnZzkf3W0ozbdu/k2QapkZfJ9zY1PnCQip+snzdmHf1iH0VJQi84NCN9MPDBEGk
+0bE5SmsstS6aZUMNDnP0BuGzSTSUsLf/wCfBteoG93Fxl7u8xxqf6/Y9pXtVp7/d
+1+6XuJ3czeMG25osYL9whPprjXB93ui3q7A4aGzAseG6ReDXEj1xWw==
-----END X509 CRL-----
diff --git a/examples/certs/crl/crl.revoked b/examples/certs/crl/crl.revoked
index 81e8021..b85ca36 100644
--- a/examples/certs/crl/crl.revoked
+++ b/examples/certs/crl/crl.revoked
@@ -2,43 +2,43 @@ Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
- Last Update: Feb 15 12:50:27 2022 GMT
- Next Update: Nov 11 12:50:27 2024 GMT
+ Last Update: Dec 16 21:17:50 2022 GMT
+ Next Update: Sep 11 21:17:50 2025 GMT
CRL extensions:
X509v3 CRL Number:
3
Revoked Certificates:
Serial Number: 01
- Revocation Date: Feb 15 12:50:27 2022 GMT
+ Revocation Date: Dec 16 21:17:50 2022 GMT
Serial Number: 02
- Revocation Date: Feb 15 12:50:27 2022 GMT
+ Revocation Date: Dec 16 21:17:50 2022 GMT
Signature Algorithm: sha256WithRSAEncryption
- 0f:69:fc:a3:54:d7:9c:94:db:71:a8:6c:b6:af:3c:df:0d:bb:
- bb:cb:2e:45:6f:6d:a5:27:dc:ee:67:39:36:d4:33:22:02:5e:
- fe:4f:27:00:4a:ba:b0:51:7c:3e:98:ee:a2:d3:58:31:6c:60:
- 02:34:f0:ec:67:ec:fa:66:44:8d:27:f7:70:57:4b:a1:10:e3:
- a1:fb:f4:3a:ac:ec:ca:cb:d8:d7:d8:ca:45:41:d4:17:18:30:
- f1:4e:f6:a4:8b:17:0c:4f:b0:b6:79:17:f3:a8:57:8f:8d:89:
- ad:73:b9:d4:95:c1:e2:19:0e:f6:ca:dd:bd:dc:d1:0b:eb:a7:
- c7:85:c6:49:8f:7d:e4:9b:fb:1a:a9:da:92:0a:52:7a:87:f3:
- 32:dc:a8:9f:cf:a3:3b:47:ee:66:f4:61:48:a0:60:4c:50:66:
- 87:07:33:55:11:ed:8b:5d:df:d8:10:de:ce:ea:4a:98:41:ca:
- 6a:90:7c:35:0d:df:ac:4d:19:d6:5f:37:a5:a7:48:40:31:59:
- 62:84:a8:21:a6:b5:8d:63:54:e0:2e:b9:83:92:b0:20:bc:66:
- b2:bf:4d:5a:0b:00:a7:c0:cb:29:c3:54:be:92:91:1d:b0:d0:
- ec:b4:5d:fe:a4:90:ed:08:21:71:18:91:4b:97:3d:75:4f:f0:
- bc:56:8e:db
+ 1f:6c:1c:50:42:8a:55:bc:41:f6:a9:15:b6:ad:90:53:0a:b8:
+ 73:71:8b:dd:0e:8f:95:0f:97:6d:82:24:09:6d:d5:9f:57:47:
+ ab:c2:10:ad:df:27:0b:6c:d4:1f:c2:d5:4b:56:4b:44:01:3e:
+ 5f:d3:08:6c:da:5b:94:40:00:47:e2:c9:f5:93:3d:c6:b0:28:
+ b6:48:ff:32:9e:7b:d9:2d:71:5c:c4:53:13:50:8d:c7:e8:d0:
+ 6f:28:ee:71:a0:8a:3e:da:9a:c4:e1:ad:a7:36:ce:87:ff:1f:
+ 32:f1:32:ca:ff:81:d9:b8:d1:ca:39:7f:08:90:77:da:45:23:
+ 56:49:ad:08:99:ef:75:23:5f:92:9a:b4:34:ef:5c:b1:68:71:
+ 0d:06:31:28:5e:b1:34:56:a3:d6:47:8a:ba:2b:e2:be:28:29:
+ d0:6a:12:60:5e:5c:93:7d:0d:54:bf:ee:72:7f:31:e6:9a:ab:
+ 56:fc:34:45:06:e9:bd:fc:39:1d:37:91:77:d2:da:96:01:a0:
+ 0d:9f:cf:b6:26:98:6b:fb:d9:ef:51:1d:df:41:6c:3c:61:5c:
+ 38:83:e4:71:51:1d:62:57:53:8b:0b:0a:b1:ac:df:5c:22:26:
+ b6:67:51:62:06:5b:97:ed:94:f4:40:7e:48:4e:3b:fd:b7:75:
+ 40:17:ec:48
-----BEGIN X509 CRL-----
MIICGTCCAQECAQEwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVTMRAwDgYD
VQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMREwDwYDVQQKDAhTYXd0b290
aDETMBEGA1UECwwKQ29uc3VsdGluZzEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29t
-MR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tFw0yMjAyMTUxMjUwMjda
-Fw0yNDExMTExMjUwMjdaMCgwEgIBARcNMjIwMjE1MTI1MDI3WjASAgECFw0yMjAy
-MTUxMjUwMjdaoA4wDDAKBgNVHRQEAwIBAzANBgkqhkiG9w0BAQsFAAOCAQEAD2n8
-o1TXnJTbcahstq883w27u8suRW9tpSfc7mc5NtQzIgJe/k8nAEq6sFF8PpjuotNY
-MWxgAjTw7Gfs+mZEjSf3cFdLoRDjofv0OqzsysvY19jKRUHUFxgw8U72pIsXDE+w
-tnkX86hXj42JrXO51JXB4hkO9srdvdzRC+unx4XGSY995Jv7GqnakgpSeofzMtyo
-n8+jO0fuZvRhSKBgTFBmhwczVRHti13f2BDezupKmEHKapB8NQ3frE0Z1l83padI
-QDFZYoSoIaa1jWNU4C65g5KwILxmsr9NWgsAp8DLKcNUvpKRHbDQ7LRd/qSQ7Qgh
-cRiRS5c9dU/wvFaO2w==
+MR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tFw0yMjEyMTYyMTE3NTBa
+Fw0yNTA5MTEyMTE3NTBaMCgwEgIBARcNMjIxMjE2MjExNzUwWjASAgECFw0yMjEy
+MTYyMTE3NTBaoA4wDDAKBgNVHRQEAwIBAzANBgkqhkiG9w0BAQsFAAOCAQEAH2wc
+UEKKVbxB9qkVtq2QUwq4c3GL3Q6PlQ+XbYIkCW3Vn1dHq8IQrd8nC2zUH8LVS1ZL
+RAE+X9MIbNpblEAAR+LJ9ZM9xrAotkj/Mp572S1xXMRTE1CNx+jQbyjucaCKPtqa
+xOGtpzbOh/8fMvEyyv+B2bjRyjl/CJB32kUjVkmtCJnvdSNfkpq0NO9csWhxDQYx
+KF6xNFaj1keKuivivigp0GoSYF5ck30NVL/ucn8x5pqrVvw0RQbpvfw5HTeRd9La
+lgGgDZ/PtiaYa/vZ71Ed30FsPGFcOIPkcVEdYldTiwsKsazfXCImtmdRYgZbl+2U
+9EB+SE47/bd1QBfsSA==
-----END X509 CRL-----
diff --git a/examples/certs/crl/eccCliCRL.pem b/examples/certs/crl/eccCliCRL.pem
index 0399310..0b51168 100644
--- a/examples/certs/crl/eccCliCRL.pem
+++ b/examples/certs/crl/eccCliCRL.pem
@@ -2,25 +2,25 @@ Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: ecdsa-with-SHA256
Issuer: C = US, ST = Oregon, L = Salem, O = Client ECC, OU = Fast, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
- Last Update: Feb 15 12:50:27 2022 GMT
- Next Update: Nov 11 12:50:27 2024 GMT
+ Last Update: Dec 16 21:17:50 2022 GMT
+ Next Update: Sep 11 21:17:50 2025 GMT
CRL extensions:
X509v3 CRL Number:
7
Revoked Certificates:
Serial Number: 02
- Revocation Date: Feb 15 12:50:27 2022 GMT
+ Revocation Date: Dec 16 21:17:50 2022 GMT
Signature Algorithm: ecdsa-with-SHA256
- 30:46:02:21:00:c3:8c:e6:ec:41:6c:c8:c7:eb:97:dd:f0:5b:
- be:bf:38:68:fe:0a:62:ff:c2:f9:23:db:98:41:0e:b1:64:b8:
- 46:02:21:00:d7:d8:77:8c:e7:c7:8a:45:9f:fe:c0:4c:bd:f4:
- 4c:aa:06:ea:5f:82:b6:8b:93:09:57:60:85:d4:82:09:7d:f8
+ 30:46:02:21:00:de:52:96:3d:ab:bf:56:6f:1b:a5:61:f2:43:
+ 38:09:61:35:be:c3:8a:7b:17:77:2c:6a:a2:94:be:db:eb:c9:
+ 54:02:21:00:8f:38:ad:28:29:42:e6:5c:65:73:d8:2e:2c:b1:
+ ba:ec:15:d9:c6:fe:48:07:bd:d9:46:1a:24:0c:0a:da:e7:8c
-----BEGIN X509 CRL-----
MIIBPTCB4wIBATAKBggqhkjOPQQDAjCBjTELMAkGA1UEBhMCVVMxDzANBgNVBAgM
Bk9yZWdvbjEOMAwGA1UEBwwFU2FsZW0xEzARBgNVBAoMCkNsaWVudCBFQ0MxDTAL
BgNVBAsMBEZhc3QxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3
-DQEJARYQaW5mb0B3b2xmc3NsLmNvbRcNMjIwMjE1MTI1MDI3WhcNMjQxMTExMTI1
-MDI3WjAUMBICAQIXDTIyMDIxNTEyNTAyN1qgDjAMMAoGA1UdFAQDAgEHMAoGCCqG
-SM49BAMCA0kAMEYCIQDDjObsQWzIx+uX3fBbvr84aP4KYv/C+SPbmEEOsWS4RgIh
-ANfYd4znx4pFn/7ATL30TKoG6l+CtouTCVdghdSCCX34
+DQEJARYQaW5mb0B3b2xmc3NsLmNvbRcNMjIxMjE2MjExNzUwWhcNMjUwOTExMjEx
+NzUwWjAUMBICAQIXDTIyMTIxNjIxMTc1MFqgDjAMMAoGA1UdFAQDAgEHMAoGCCqG
+SM49BAMCA0kAMEYCIQDeUpY9q79WbxulYfJDOAlhNb7DinsXdyxqopS+2+vJVAIh
+AI84rSgpQuZcZXPYLiyxuuwV2cb+SAe92UYaJAwK2ueM
-----END X509 CRL-----
diff --git a/examples/certs/crl/eccSrvCRL.pem b/examples/certs/crl/eccSrvCRL.pem
index 9d5ce3d..cf3b068 100644
--- a/examples/certs/crl/eccSrvCRL.pem
+++ b/examples/certs/crl/eccSrvCRL.pem
@@ -2,25 +2,25 @@ Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: ecdsa-with-SHA256
Issuer: C = US, ST = Washington, L = Seattle, O = Eliptic, OU = ECC, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
- Last Update: Feb 15 12:50:27 2022 GMT
- Next Update: Nov 11 12:50:27 2024 GMT
+ Last Update: Dec 16 21:17:50 2022 GMT
+ Next Update: Sep 11 21:17:50 2025 GMT
CRL extensions:
X509v3 CRL Number:
8
Revoked Certificates:
Serial Number: 02
- Revocation Date: Feb 15 12:50:27 2022 GMT
+ Revocation Date: Dec 16 21:17:50 2022 GMT
Signature Algorithm: ecdsa-with-SHA256
- 30:46:02:21:00:df:77:ba:80:37:b2:31:55:06:a9:96:02:6f:
- 53:1c:8f:a7:ab:69:43:37:e8:23:35:5a:42:db:71:cd:b7:7c:
- a2:02:21:00:f1:cf:b2:64:30:18:a3:52:0d:04:ad:89:ae:a2:
- 43:35:60:b4:90:0f:12:63:c7:87:7f:24:6e:c8:33:af:39:1e
+ 30:46:02:21:00:df:3b:2d:3e:14:df:73:4d:43:71:47:aa:5b:
+ a3:2f:19:8f:26:8c:e7:20:60:20:75:d7:4b:68:9e:d6:a9:f4:
+ 44:02:21:00:ec:32:6d:22:c4:bd:98:85:1b:66:9c:00:2b:5e:
+ c3:0f:cd:cc:54:a4:0a:2c:e9:bb:32:18:8f:27:d3:a3:d4:84
-----BEGIN X509 CRL-----
MIIBPzCB5QIBATAKBggqhkjOPQQDAjCBjzELMAkGA1UEBhMCVVMxEzARBgNVBAgM
Cldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB0VsaXB0aWMx
DDAKBgNVBAsMA0VDQzEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZI
-hvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tFw0yMjAyMTUxMjUwMjdaFw0yNDExMTEx
-MjUwMjdaMBQwEgIBAhcNMjIwMjE1MTI1MDI3WqAOMAwwCgYDVR0UBAMCAQgwCgYI
-KoZIzj0EAwIDSQAwRgIhAN93uoA3sjFVBqmWAm9THI+nq2lDN+gjNVpC23HNt3yi
-AiEA8c+yZDAYo1INBK2JrqJDNWC0kA8SY8eHfyRuyDOvOR4=
+hvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tFw0yMjEyMTYyMTE3NTBaFw0yNTA5MTEy
+MTE3NTBaMBQwEgIBAhcNMjIxMjE2MjExNzUwWqAOMAwwCgYDVR0UBAMCAQgwCgYI
+KoZIzj0EAwIDSQAwRgIhAN87LT4U33NNQ3FHqlujLxmPJoznIGAgdddLaJ7WqfRE
+AiEA7DJtIsS9mIUbZpwAK17DD83MVKQKLOm7MhiPJ9Oj1IQ=
-----END X509 CRL-----
diff --git a/examples/certs/server-cert.pem b/examples/certs/server-cert.pem
index 75c6f83..de754a2 100644
--- a/examples/certs/server-cert.pem
+++ b/examples/certs/server-cert.pem
@@ -5,8 +5,8 @@ Certificate:
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Validity
- Not Before: Feb 15 12:50:24 2022 GMT
- Not After : Nov 11 12:50:24 2024 GMT
+ Not Before: Dec 16 21:17:49 2022 GMT
+ Not After : Sep 11 21:17:49 2025 GMT
Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL, OU = Support, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
@@ -37,7 +37,7 @@ Certificate:
X509v3 Authority Key Identifier:
keyid:27:8E:67:11:74:C3:26:1D:3F:ED:33:63:B3:A4:D8:1D:30:E5:E8:D5
DirName:/C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
- serial:26:8C:93:F9:F9:F4:1E:B3:01:72:94:55:67:6D:E2:F8:3D:DA:E9:F4
+ serial:2C:80:CE:DB:47:9D:07:66:92:3D:68:D7:CA:AC:90:4F:CA:69:41:4B
X509v3 Basic Constraints:
CA:TRUE
@@ -46,27 +46,27 @@ Certificate:
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Signature Algorithm: sha256WithRSAEncryption
- 4b:88:54:a8:57:f0:62:4d:b3:c5:8c:d2:02:0a:89:19:45:63:
- 8e:37:5c:a9:f7:8c:c5:7c:9d:19:b4:5d:b6:a4:29:4d:97:da:
- 6e:3c:27:ec:02:5c:fb:e2:93:6f:b6:1a:dc:5e:25:1f:be:ab:
- 6f:37:ff:d6:98:67:7c:f7:53:84:3b:e6:f7:22:ef:52:b0:8f:
- 9d:4e:2f:41:2a:7d:2f:f8:02:1e:f5:cd:9a:b2:68:68:d6:ef:
- ed:6a:96:a0:84:6f:0c:5e:7b:44:f9:6f:d0:00:6f:dd:83:6a:
- d9:d9:17:9d:32:9a:ea:4b:87:f9:12:45:3e:b8:de:20:fe:f4:
- b8:3f:f4:99:61:a6:2b:97:1b:7c:a0:90:cf:e9:3b:cd:94:ce:
- 85:df:fb:6a:2b:67:5b:8c:28:de:e6:0b:4b:68:5b:b3:4a:3e:
- 10:3b:0c:d8:c8:f1:3e:3d:cc:2f:16:76:24:43:b6:3b:fd:cf:
- 2f:07:0f:15:31:59:5e:cd:84:a9:82:05:1f:0c:97:56:5d:90:
- 49:bd:84:47:ec:07:b9:cf:fa:a0:56:9b:ae:e2:a9:96:b2:62:
- 02:4a:fa:42:d5:23:dc:1c:6b:5c:41:3d:f2:73:e8:ed:32:93:
- cc:f7:02:5a:b4:be:84:ca:73:26:9f:03:2c:b3:74:96:20:7e:
- 12:ea:e5:ef
+ b9:10:f0:be:fe:c8:67:5e:7d:0f:36:33:c7:17:2a:01:c4:bb:
+ 74:83:4c:bc:bb:e2:ba:92:82:3a:d9:2d:8c:0e:e3:75:1b:c0:
+ 14:aa:40:1e:a8:11:7d:94:9c:3d:74:7a:3b:16:7b:d8:9d:f0:
+ e8:7d:1d:fa:3b:14:42:20:e3:05:a3:fd:b1:0c:f1:2a:c4:00:
+ 50:8d:1e:97:93:6a:de:82:13:24:9e:2b:fa:08:85:e3:4f:40:
+ fd:63:c7:3d:e9:bd:6f:7c:03:98:85:fe:b4:51:5d:7f:8c:83:
+ b3:ad:4a:88:e9:f3:4c:33:84:77:d3:02:35:59:e3:4e:64:a1:
+ b7:bb:fb:f8:fb:14:2a:ae:36:bf:d9:82:e7:cb:98:48:16:c8:
+ 81:d6:a0:f1:74:14:e3:74:4a:72:4a:f1:6f:dd:be:86:1e:20:
+ f3:05:16:83:1f:aa:7c:59:35:97:24:b8:27:b7:56:9f:30:2e:
+ 90:e0:19:e0:21:ca:9d:3f:da:99:07:94:79:49:53:14:5c:a2:
+ 2c:56:5b:b2:55:68:5c:1f:91:58:9a:cd:53:b5:ea:63:5a:72:
+ 49:41:cc:76:9f:88:35:86:0d:60:5d:e5:91:bd:ac:6f:cf:d5:
+ 92:27:72:4a:21:f4:58:98:8e:3b:d2:29:e6:ee:fa:e6:b0:6c:
+ 8b:1e:e0:54
-----BEGIN CERTIFICATE-----
MIIE6DCCA9CgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBlDELMAkGA1UEBhMCVVMx
EDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNh
d3Rvb3RoMRMwEQYDVQQLDApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNz
-bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjIwMjE1
-MTI1MDI0WhcNMjQxMTExMTI1MDI0WjCBkDELMAkGA1UEBhMCVVMxEDAOBgNVBAgM
+bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjIxMjE2
+MjExNzQ5WhcNMjUwOTExMjExNzQ5WjCBkDELMAkGA1UEBhMCVVMxEDAOBgNVBAgM
B01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xEDAOBgNVBAoMB3dvbGZTU0wxEDAO
BgNVBAsMB1N1cHBvcnQxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG
SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
@@ -80,26 +80,26 @@ BBSzETLJkpiE4sn40DtuA0LKHw6OPDCB1AYDVR0jBIHMMIHJgBQnjmcRdMMmHT/t
M2OzpNgdMOXo1aGBmqSBlzCBlDELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB01vbnRh
bmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNhd3Rvb3RoMRMwEQYDVQQL
DApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG
-9w0BCQEWEGluZm9Ad29sZnNzbC5jb22CFCaMk/n59B6zAXKUVWdt4vg92un0MAwG
+9w0BCQEWEGluZm9Ad29sZnNzbC5jb22CFCyAzttHnQdmkj1o18qskE/KaUFLMAwG
A1UdEwQFMAMBAf8wHAYDVR0RBBUwE4ILZXhhbXBsZS5jb22HBH8AAAEwHQYDVR0l
-BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBLiFSo
-V/BiTbPFjNICCokZRWOON1yp94zFfJ0ZtF22pClNl9puPCfsAlz74pNvthrcXiUf
-vqtvN//WmGd891OEO+b3Iu9SsI+dTi9BKn0v+AIe9c2asmho1u/tapaghG8MXntE
-+W/QAG/dg2rZ2RedMprqS4f5EkU+uN4g/vS4P/SZYaYrlxt8oJDP6TvNlM6F3/tq
-K2dbjCje5gtLaFuzSj4QOwzYyPE+PcwvFnYkQ7Y7/c8vBw8VMVlezYSpggUfDJdW
-XZBJvYRH7Ae5z/qgVpuu4qmWsmICSvpC1SPcHGtcQT3yc+jtMpPM9wJatL6EynMm
-nwMss3SWIH4S6uXv
+BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQC5EPC+
+/shnXn0PNjPHFyoBxLt0g0y8u+K6koI62S2MDuN1G8AUqkAeqBF9lJw9dHo7FnvY
+nfDofR36OxRCIOMFo/2xDPEqxABQjR6Xk2reghMkniv6CIXjT0D9Y8c96b1vfAOY
+hf60UV1/jIOzrUqI6fNMM4R30wI1WeNOZKG3u/v4+xQqrja/2YLny5hIFsiB1qDx
+dBTjdEpySvFv3b6GHiDzBRaDH6p8WTWXJLgnt1afMC6Q4BngIcqdP9qZB5R5SVMU
+XKIsVluyVWhcH5FYms1TtepjWnJJQcx2n4g1hg1gXeWRvaxvz9WSJ3JKIfRYmI47
+0inm7vrmsGyLHuBU
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
- 26:8c:93:f9:f9:f4:1e:b3:01:72:94:55:67:6d:e2:f8:3d:da:e9:f4
+ 2c:80:ce:db:47:9d:07:66:92:3d:68:d7:ca:ac:90:4f:ca:69:41:4b
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Validity
- Not Before: Feb 15 12:50:24 2022 GMT
- Not After : Nov 11 12:50:24 2024 GMT
+ Not Before: Dec 16 21:17:49 2022 GMT
+ Not After : Sep 11 21:17:49 2025 GMT
Subject: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
@@ -130,7 +130,7 @@ Certificate:
X509v3 Authority Key Identifier:
keyid:27:8E:67:11:74:C3:26:1D:3F:ED:33:63:B3:A4:D8:1D:30:E5:E8:D5
DirName:/C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
- serial:26:8C:93:F9:F9:F4:1E:B3:01:72:94:55:67:6D:E2:F8:3D:DA:E9:F4
+ serial:2C:80:CE:DB:47:9D:07:66:92:3D:68:D7:CA:AC:90:4F:CA:69:41:4B
X509v3 Basic Constraints:
CA:TRUE
@@ -139,27 +139,27 @@ Certificate:
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
Signature Algorithm: sha256WithRSAEncryption
- 62:e4:1b:28:3c:9d:d2:60:a9:55:be:6a:f6:20:f2:da:e8:a1:
- 1a:97:b1:90:77:82:ed:c7:77:29:53:33:18:10:62:e0:bd:93:
- 1b:d2:d6:a1:80:43:1d:64:f1:42:92:ec:b7:b8:f0:6b:da:59:
- 83:f4:b8:87:e6:fc:70:21:ea:62:32:70:68:14:0e:dc:b4:f1:
- 66:e2:6e:ab:d2:72:6f:da:df:71:f6:3d:27:97:7d:be:e1:d1:
- ac:16:ad:d7:4f:aa:9d:0c:1e:6e:a9:5e:7d:57:5b:3c:c7:6d:
- d2:f2:5c:c3:dc:3d:36:99:8e:ab:c0:7f:13:a5:f4:67:8b:e2:
- a6:51:31:f1:03:91:00:a8:c4:c5:1d:7f:35:62:b8:1d:a0:a5:
- ab:ec:32:68:ee:f3:ca:48:16:9f:f4:1e:7e:ea:fa:b0:86:15:
- 52:36:6c:4b:58:44:a7:eb:20:78:6e:7e:e8:00:40:ac:98:d8:
- 53:f3:13:4b:b8:98:66:50:63:ed:af:e5:a4:f6:c9:90:1c:84:
- 0a:09:45:2f:a1:e1:37:63:b5:43:8c:a0:2e:7f:c4:d4:e1:ae:
- b7:b9:45:13:f8:70:d5:79:06:4f:82:83:4b:98:d7:56:47:64:
- 9a:6a:6d:8e:7a:9d:ef:83:0f:6b:75:0e:47:22:92:f3:b4:b2:
- 84:61:1f:1c
+ ae:b0:a4:35:8e:8a:1b:a6:eb:b3:a2:57:cf:3a:1f:dc:6e:bc:
+ d2:d0:a6:4a:8f:88:0a:6e:74:d5:d1:7c:d1:44:b1:d4:3b:17:
+ 03:09:5a:46:ed:08:08:cf:f1:fd:20:07:67:c0:97:ec:35:f3:
+ 75:ca:20:61:98:3e:f5:4d:be:e6:9d:75:1e:e4:03:ad:8c:a6:
+ 1e:3d:ec:e4:1a:92:5b:f9:a3:ad:83:ca:4f:cd:aa:38:bb:6e:
+ ae:ad:fa:a7:46:f1:8b:73:ec:09:23:bc:f2:18:e5:b7:92:86:
+ 3e:a4:75:60:c7:3d:0f:3f:83:00:c3:06:08:9c:d1:54:d6:ba:
+ 6d:95:3d:34:a1:be:24:91:cc:20:03:11:5b:72:1c:d4:65:d0:
+ 11:88:75:26:04:26:ef:66:70:e6:3b:38:87:9c:53:71:1b:09:
+ 51:70:50:99:4c:31:0c:62:44:57:30:60:04:fc:12:2c:a3:24:
+ b4:f7:11:d5:0e:b5:21:0b:ed:86:11:67:4d:36:fa:57:a0:59:
+ 55:21:b3:6d:e4:77:5e:ec:7e:f0:09:13:8e:99:98:b2:e1:82:
+ b6:4b:3e:0f:41:a6:0c:cd:49:99:7e:e4:8a:cb:37:ed:53:cf:
+ 86:5d:a9:26:a8:e5:01:25:5a:b4:bc:25:35:f1:fa:5a:5c:ce:
+ d4:b8:9a:2c
-----BEGIN CERTIFICATE-----
-MIIE/zCCA+egAwIBAgIUJoyT+fn0HrMBcpRVZ23i+D3a6fQwDQYJKoZIhvcNAQEL
+MIIE/zCCA+egAwIBAgIULIDO20edB2aSPWjXyqyQT8ppQUswDQYJKoZIhvcNAQEL
BQAwgZQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdC
b3plbWFuMREwDwYDVQQKDAhTYXd0b290aDETMBEGA1UECwwKQ29uc3VsdGluZzEY
MBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdv
-bGZzc2wuY29tMB4XDTIyMDIxNTEyNTAyNFoXDTI0MTExMTEyNTAyNFowgZQxCzAJ
+bGZzc2wuY29tMB4XDTIyMTIxNjIxMTc0OVoXDTI1MDkxMTIxMTc0OVowgZQxCzAJ
BgNVBAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMREw
DwYDVQQKDAhTYXd0b290aDETMBEGA1UECwwKQ29uc3VsdGluZzEYMBYGA1UEAwwP
d3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29t
@@ -174,12 +174,12 @@ BgNVHSMEgcwwgcmAFCeOZxF0wyYdP+0zY7Ok2B0w5ejVoYGapIGXMIGUMQswCQYD
VQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjERMA8G
A1UECgwIU2F3dG9vdGgxEzARBgNVBAsMCkNvbnN1bHRpbmcxGDAWBgNVBAMMD3d3
dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbYIU
-JoyT+fn0HrMBcpRVZ23i+D3a6fQwDAYDVR0TBAUwAwEB/zAcBgNVHREEFTATggtl
+LIDO20edB2aSPWjXyqyQT8ppQUswDAYDVR0TBAUwAwEB/zAcBgNVHREEFTATggtl
eGFtcGxlLmNvbYcEfwAAATAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
-DQYJKoZIhvcNAQELBQADggEBAGLkGyg8ndJgqVW+avYg8trooRqXsZB3gu3HdylT
-MxgQYuC9kxvS1qGAQx1k8UKS7Le48GvaWYP0uIfm/HAh6mIycGgUDty08WbibqvS
-cm/a33H2PSeXfb7h0awWrddPqp0MHm6pXn1XWzzHbdLyXMPcPTaZjqvAfxOl9GeL
-4qZRMfEDkQCoxMUdfzViuB2gpavsMmju88pIFp/0Hn7q+rCGFVI2bEtYRKfrIHhu
-fugAQKyY2FPzE0u4mGZQY+2v5aT2yZAchAoJRS+h4TdjtUOMoC5/xNThrre5RRP4
-cNV5Bk+Cg0uY11ZHZJpqbY56ne+DD2t1DkcikvO0soRhHxw=
+DQYJKoZIhvcNAQELBQADggEBAK6wpDWOihum67OiV886H9xuvNLQpkqPiApudNXR
+fNFEsdQ7FwMJWkbtCAjP8f0gB2fAl+w183XKIGGYPvVNvuaddR7kA62Mph497OQa
+klv5o62Dyk/Nqji7bq6t+qdG8Ytz7AkjvPIY5beShj6kdWDHPQ8/gwDDBgic0VTW
+um2VPTShviSRzCADEVtyHNRl0BGIdSYEJu9mcOY7OIecU3EbCVFwUJlMMQxiRFcw
+YAT8EiyjJLT3EdUOtSEL7YYRZ002+legWVUhs23kd17sfvAJE46ZmLLhgrZLPg9B
+pgzNSZl+5IrLN+1Tz4ZdqSao5QElWrS8JTXx+lpcztS4miw=
-----END CERTIFICATE-----
diff --git a/examples/certs/server-ecc.pem b/examples/certs/server-ecc.pem
index 24d3d40..d2f48f9 100644
--- a/examples/certs/server-ecc.pem
+++ b/examples/certs/server-ecc.pem
@@ -5,8 +5,8 @@ Certificate:
Signature Algorithm: ecdsa-with-SHA256
Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Development, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Validity
- Not Before: Feb 15 12:50:24 2022 GMT
- Not After : Nov 11 12:50:24 2024 GMT
+ Not Before: Dec 16 21:17:49 2022 GMT
+ Not After : Sep 11 21:17:49 2025 GMT
Subject: C = US, ST = Washington, L = Seattle, O = Eliptic, OU = ECC, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
@@ -34,16 +34,16 @@ Certificate:
Netscape Cert Type:
SSL Server
Signature Algorithm: ecdsa-with-SHA256
- 30:45:02:20:5b:9d:f4:69:17:88:c0:13:34:3d:81:81:dc:fb:
- 27:7c:a0:63:00:87:d5:48:e1:9c:57:c9:01:c1:d2:5f:30:58:
- 02:21:00:89:93:a5:b6:04:de:4d:3d:98:ed:0b:ce:3a:74:3e:
- 6c:f1:80:1f:28:d8:ee:78:af:da:8a:3b:b4:27:38:e2:b1
+ 30:45:02:21:00:cf:3a:17:97:d4:be:7c:50:e1:be:1b:53:95:
+ 7b:a3:b8:c6:73:c4:34:e0:73:5a:db:3e:cb:3a:b6:a8:f1:cd:
+ bf:02:20:2b:e6:f9:65:b2:ab:0f:bb:2b:36:5c:cc:2e:19:a9:
+ 59:1c:6f:6f:ce:9b:7a:e6:5b:65:31:33:80:05:cb:7c:96
-----BEGIN CERTIFICATE-----
MIICoTCCAkegAwIBAgIBAzAKBggqhkjOPQQDAjCBlzELMAkGA1UEBhMCVVMxEzAR
BgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dv
bGZTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50MRgwFgYDVQQDDA93d3cud29sZnNz
-bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjIwMjE1
-MTI1MDI0WhcNMjQxMTExMTI1MDI0WjCBjzELMAkGA1UEBhMCVVMxEzARBgNVBAgM
+bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjIxMjE2
+MjExNzQ5WhcNMjUwOTExMjExNzQ5WjCBjzELMAkGA1UEBhMCVVMxEzARBgNVBAgM
Cldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB0VsaXB0aWMx
DDAKBgNVBAsMA0VDQzEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZI
hvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
@@ -51,7 +51,7 @@ QgAEuzOsTCdQSsZKpQTDPN6fNttyLc6U6iv6yyAJOSwW6GEC6a9N0wKTmjFbl5Ih
f/DPGNqREQI0huggWDMLgDSJ2KOBiTCBhjAdBgNVHQ4EFgQUXV0m76x+NvmbdhUr
SiUCI++yiTAwHwYDVR0jBBgwFoAUVo6aw/BC3hi5RVVu+ZPP6sPzpSEwDAYDVR0T
AQH/BAIwADAOBgNVHQ8BAf8EBAMCA6gwEwYDVR0lBAwwCgYIKwYBBQUHAwEwEQYJ
-YIZIAYb4QgEBBAQDAgZAMAoGCCqGSM49BAMCA0gAMEUCIFud9GkXiMATND2Bgdz7
-J3ygYwCH1UjhnFfJAcHSXzBYAiEAiZOltgTeTT2Y7QvOOnQ+bPGAHyjY7niv2oo7
-tCc44rE=
+YIZIAYb4QgEBBAQDAgZAMAoGCCqGSM49BAMCA0gAMEUCIQDPOheX1L58UOG+G1OV
+e6O4xnPENOBzWts+yzq2qPHNvwIgK+b5ZbKrD7srNlzMLhmpWRxvb86beuZbZTEz
+gAXLfJY=
-----END CERTIFICATE-----
diff --git a/examples/certs/update-certs.sh b/examples/certs/update-certs.sh
index 2e1ac4a..c113aeb 100755
--- a/examples/certs/update-certs.sh
+++ b/examples/certs/update-certs.sh
@@ -34,9 +34,12 @@ certList=(
"ca-ecc-cert.pem"
"ca-ecc-key.pem"
"ca-key.pem"
+ "ca-key.der"
"client-cert.der"
"client-cert.pem"
"client-key.pem"
+ "client-key.der"
+ "client-keyPub.der"
"dh2048.pem"
"ecc-client-key.pem"
"ecc-key.pem"
@@ -66,14 +69,30 @@ do
fi
done
+# Generate ca-keyPkcs8.der, used by examples/X509CertificateGeneration.java
+openssl pkcs8 -topk8 -inform DER -outform DER -in ca-key.der -out ca-keyPkcs8.der -nocrypt
+if [ $? -ne 0 ]; then
+ printf "Failed to generate ca-keyPkcs8.der"
+ exit 1
+fi
+printf "Generated ca-keyPkcs8.der\n"
+
# Remove text info from intermediate certs, causes issues on Android (WRONG TAG)
printf "Removing text info from intermediate certs\n"
-sed -i -n '/-----BEGIN CERTIFICATE-----/,$p' intermediate/ca-int2-cert.pem
-sed -i -n '/-----BEGIN CERTIFICATE-----/,$p' intermediate/ca-int2-ecc-cert.pem
-sed -i -n '/-----BEGIN CERTIFICATE-----/,$p' intermediate/ca-int-cert.pem
-sed -i -n '/-----BEGIN CERTIFICATE-----/,$p' intermediate/ca-int-ecc-cert.pem
-sed -i -n '/-----BEGIN CERTIFICATE-----/,$p' intermediate/server-int-cert.pem
-sed -i -n '/-----BEGIN CERTIFICATE-----/,$p' intermediate/server-int-ecc-cert.pem
+sed -i.bak -n '/-----BEGIN CERTIFICATE-----/,$p' intermediate/ca-int2-cert.pem
+sed -i.bak -n '/-----BEGIN CERTIFICATE-----/,$p' intermediate/ca-int2-ecc-cert.pem
+sed -i.bak -n '/-----BEGIN CERTIFICATE-----/,$p' intermediate/ca-int-cert.pem
+sed -i.bak -n '/-----BEGIN CERTIFICATE-----/,$p' intermediate/ca-int-ecc-cert.pem
+sed -i.bak -n '/-----BEGIN CERTIFICATE-----/,$p' intermediate/server-int-cert.pem
+sed -i.bak -n '/-----BEGIN CERTIFICATE-----/,$p' intermediate/server-int-ecc-cert.pem
+
+# Remvoe sed .bak files
+rm intermediate/ca-int2-cert.pem.bak
+rm intermediate/ca-int2-ecc-cert.pem.bak
+rm intermediate/ca-int-cert.pem.bak
+rm intermediate/ca-int-ecc-cert.pem.bak
+rm intermediate/server-int-cert.pem.bak
+rm intermediate/server-int-ecc-cert.pem.bak
printf "Finished successfully\n"
diff --git a/examples/provider/all.jks b/examples/provider/all.jks
index 8773fb8..46376f2 100644
Binary files a/examples/provider/all.jks and b/examples/provider/all.jks differ
diff --git a/examples/provider/all_mixed.jks b/examples/provider/all_mixed.jks
index 706db39..bec480a 100644
Binary files a/examples/provider/all_mixed.jks and b/examples/provider/all_mixed.jks differ
diff --git a/examples/provider/ca-client.jks b/examples/provider/ca-client.jks
index 7f86494..7fb9c55 100644
Binary files a/examples/provider/ca-client.jks and b/examples/provider/ca-client.jks differ
diff --git a/examples/provider/ca-server.jks b/examples/provider/ca-server.jks
index e4673d7..ccfc2be 100644
Binary files a/examples/provider/ca-server.jks and b/examples/provider/ca-server.jks differ
diff --git a/examples/provider/cacerts.jks b/examples/provider/cacerts.jks
index bc32113..d05f055 100644
Binary files a/examples/provider/cacerts.jks and b/examples/provider/cacerts.jks differ
diff --git a/examples/provider/client-ecc.jks b/examples/provider/client-ecc.jks
index 8419abb..df96030 100644
Binary files a/examples/provider/client-ecc.jks and b/examples/provider/client-ecc.jks differ
diff --git a/examples/provider/client-rsa-1024.jks b/examples/provider/client-rsa-1024.jks
index b9a3447..da53582 100644
Binary files a/examples/provider/client-rsa-1024.jks and b/examples/provider/client-rsa-1024.jks differ
diff --git a/examples/provider/client-rsa.jks b/examples/provider/client-rsa.jks
index 14328f2..dff623f 100644
Binary files a/examples/provider/client-rsa.jks and b/examples/provider/client-rsa.jks differ
diff --git a/examples/provider/client.jks b/examples/provider/client.jks
index d047734..5ef402c 100644
Binary files a/examples/provider/client.jks and b/examples/provider/client.jks differ
diff --git a/examples/provider/server-ecc.jks b/examples/provider/server-ecc.jks
index 77cda05..118ffb8 100644
Binary files a/examples/provider/server-ecc.jks and b/examples/provider/server-ecc.jks differ
diff --git a/examples/provider/server-rsa-1024.jks b/examples/provider/server-rsa-1024.jks
index 316805c..f674bea 100644
Binary files a/examples/provider/server-rsa-1024.jks and b/examples/provider/server-rsa-1024.jks differ
diff --git a/examples/provider/server-rsa.jks b/examples/provider/server-rsa.jks
index fdae9ff..f2b99fc 100644
Binary files a/examples/provider/server-rsa.jks and b/examples/provider/server-rsa.jks differ
diff --git a/examples/provider/server.jks b/examples/provider/server.jks
index b5f1268..23d05ee 100644
Binary files a/examples/provider/server.jks and b/examples/provider/server.jks differ
diff --git a/java.sh b/java.sh
index b5fa16e..cfbc258 100755
--- a/java.sh
+++ b/java.sh
@@ -116,8 +116,9 @@ gcc -Wall -c $fpic $cflags ./native/com_wolfssl_wolfcrypt_ECC.c -o ./native/com_
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_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_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_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
diff --git a/native/com_wolfssl_WolfSSL.c b/native/com_wolfssl_WolfSSL.c
index f46e740..3d315a2 100644
--- a/native/com_wolfssl_WolfSSL.c
+++ b/native/com_wolfssl_WolfSSL.c
@@ -1147,6 +1147,12 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getHmacMaxSize
return WC_MAX_DIGEST_SIZE;
}
+JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSL_getLibVersionHex
+ (JNIEnv* jenv, jclass jcl)
+{
+ return (jlong)wolfSSL_lib_version_hex();
+}
+
JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSL_getEnabledCipherSuites
(JNIEnv* jenv, jclass jcl)
{
diff --git a/native/com_wolfssl_WolfSSL.h b/native/com_wolfssl_WolfSSL.h
index a6589d4..c4b71e3 100644
--- a/native/com_wolfssl_WolfSSL.h
+++ b/native/com_wolfssl_WolfSSL.h
@@ -199,6 +199,26 @@ extern "C" {
#define com_wolfssl_WolfSSL_ECDSAk 518L
#undef com_wolfssl_WolfSSL_ED25519k
#define com_wolfssl_WolfSSL_ED25519k 256L
+#undef com_wolfssl_WolfSSL_ASN_OTHER_TYPE
+#define com_wolfssl_WolfSSL_ASN_OTHER_TYPE 0L
+#undef com_wolfssl_WolfSSL_ASN_RFC822_TYPE
+#define com_wolfssl_WolfSSL_ASN_RFC822_TYPE 1L
+#undef com_wolfssl_WolfSSL_ASN_DNS_TYPE
+#define com_wolfssl_WolfSSL_ASN_DNS_TYPE 2L
+#undef com_wolfssl_WolfSSL_ASN_DIR_TYPE
+#define com_wolfssl_WolfSSL_ASN_DIR_TYPE 4L
+#undef com_wolfssl_WolfSSL_ASN_URI_TYPE
+#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_key_usage
+#define com_wolfssl_WolfSSL_NID_key_usage 129L
+#undef com_wolfssl_WolfSSL_NID_subject_alt_name
+#define com_wolfssl_WolfSSL_NID_subject_alt_name 131L
+#undef com_wolfssl_WolfSSL_NID_basic_constraints
+#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_WOLFSSL_NAMED_GROUP_INVALID
#define com_wolfssl_WolfSSL_WOLFSSL_NAMED_GROUP_INVALID 0L
#undef com_wolfssl_WolfSSL_WOLFSSL_ECC_SECT163K1
@@ -729,6 +749,14 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSL_x509_1getDer
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_getHmacMaxSize
(JNIEnv *, jclass);
+/*
+ * Class: com_wolfssl_WolfSSL
+ * Method: getLibVersionHex
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSL_getLibVersionHex
+ (JNIEnv *, jclass);
+
/*
* Class: com_wolfssl_WolfSSL
* Method: isEnabledCRL
diff --git a/native/com_wolfssl_WolfSSLCertificate.c b/native/com_wolfssl_WolfSSLCertificate.c
index fa410cb..d9863b7 100644
--- a/native/com_wolfssl_WolfSSLCertificate.c
+++ b/native/com_wolfssl_WolfSSLCertificate.c
@@ -38,6 +38,672 @@
#include "com_wolfssl_globals.h"
#include "com_wolfssl_WolfSSLCertificate.h"
+JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1new
+ (JNIEnv* jenv, jclass jcl)
+{
+ WOLFSSL_X509* x509 = NULL;
+ (void)jcl;
+
+ if (jenv == NULL) {
+ return 0;
+ }
+
+ x509 = wolfSSL_X509_new();
+ if (x509 == NULL) {
+ return 0;
+ }
+
+ return (jlong)(uintptr_t)x509;
+}
+
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1subject_1name
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr, jlong x509NamePtr)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
+ (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+ WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
+ 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_set_subject_name(x509, x509Name);
+
+ return ret;
+#else
+ (void)jenv;
+ (void)jcl;
+ (void)x509Ptr;
+ (void)x509NamePtr;
+ return (jint)NOT_COMPILED_IN;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1issuer_1name
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr, jlong x509NamePtr)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
+ (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+ WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
+ 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_set_issuer_name(x509, x509Name);
+
+ return ret;
+#else
+ (void)jenv;
+ (void)jcl;
+ (void)x509Ptr;
+ (void)x509NamePtr;
+ return (jint)NOT_COMPILED_IN;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1issuer_1name_1from_1der
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr, jbyteArray certDer)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
+ (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+ WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
+ WOLFSSL_X509* x509In = NULL;
+ WOLFSSL_X509_NAME* name = NULL;
+ byte* der = NULL;
+ int derSz = 0;
+ int ret = WOLFSSL_SUCCESS;
+ (void)jcl;
+
+ if (jenv == NULL || x509 == NULL || certDer == NULL) {
+ return WOLFSSL_FAILURE;
+ }
+
+ der = (byte*)(*jenv)->GetByteArrayElements(jenv, certDer, NULL);
+ derSz = (*jenv)->GetArrayLength(jenv, certDer);
+
+ if (der == NULL || derSz <= 0) {
+ ret = WOLFSSL_FAILURE;
+ }
+
+ if (ret == WOLFSSL_SUCCESS) {
+ x509In = wolfSSL_X509_load_certificate_buffer(der, derSz,
+ SSL_FILETYPE_ASN1);
+ if (x509In == NULL) {
+ ret = WOLFSSL_FAILURE;
+ }
+ }
+
+ if (ret == WOLFSSL_SUCCESS) {
+ /* Returns pointer into WOLFSSL_X509, no free needed on name */
+ name = wolfSSL_X509_get_issuer_name(x509In);
+ if (name == NULL) {
+ ret = WOLFSSL_FAILURE;
+ }
+ }
+
+ if (ret == WOLFSSL_SUCCESS) {
+ ret = wolfSSL_X509_set_issuer_name(x509, name);
+ }
+
+ if (x509In != NULL) {
+ wolfSSL_X509_free(x509In);
+ }
+
+ (*jenv)->ReleaseByteArrayElements(jenv, certDer, (jbyte*)der, JNI_ABORT);
+
+ return ret;
+#else
+ (void)jenv;
+ (void)jcl;
+ (void)x509Ptr;
+ (void)certDer;
+ return (jint)NOT_COMPILED_IN;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1pubkey_1native_1open
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr, 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)x509Ptr;
+
+ byte* fileBuf = NULL;
+ int fileSz = 0;
+ byte* derBuf = NULL;
+ 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)x509Ptr;
+ (void)keyType;
+ (void)filePath;
+ (void)fileFormat;
+ return (jint)NOT_COMPILED_IN;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1altname
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr, jstring altName, jint type)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
+ WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
+ const char* name = NULL;
+ int ret = WOLFSSL_SUCCESS;
+ (void)jcl;
+
+ if (jenv == NULL || x509 == NULL) {
+ return WOLFSSL_FAILURE;
+ }
+
+ name = (*jenv)->GetStringUTFChars(jenv, altName, 0);
+
+ if (name == NULL) {
+ ret = WOLFSSL_FAILURE;
+ }
+ else {
+ ret = wolfSSL_X509_add_altname(x509, name, (int)type);
+ }
+
+ (*jenv)->ReleaseStringUTFChars(jenv, altName, name);
+
+ return (jint)ret;
+#else
+ (void)jenv;
+ (void)jcl;
+ (void)x509Ptr;
+ (void)altName;
+ (void)type;
+ return (jint)NOT_COMPILED_IN;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1ext_1via_1nconf_1nid
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr, jint nid, jstring extValue, jboolean isCritical)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
+ WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
+ 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)x509Ptr;
+ (void)nid;
+ (void)extValue;
+ (void)isCritical;
+ return (jint)NOT_COMPILED_IN;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1ext_1via_1set_1object_1boolean
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr, jint nid, jboolean extValue, jboolean isCritical)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
+ WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
+ 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)x509Ptr;
+ (void)nid;
+ (void)extValue;
+ (void)isCritical;
+ return (jint)NOT_COMPILED_IN;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1notBefore
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr, jlong notBefore)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
+ (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+
+ WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
+ WOLFSSL_ASN1_TIME* asnBefore = NULL;
+ int ret = WOLFSSL_SUCCESS;
+ time_t notBeforeTime = (time_t)(long)notBefore;
+ (void)jcl;
+
+ if (jenv == NULL || x509 == NULL) {
+ return WOLFSSL_FAILURE;
+ }
+
+ /* set time_t value into WOLFSSL_ASN1_TIME struct, no adjustment */
+ asnBefore = wolfSSL_ASN1_TIME_adj(NULL, notBeforeTime, 0, 0);
+ if (asnBefore == NULL) {
+ ret = WOLFSSL_FAILURE;
+ }
+
+ if (ret == WOLFSSL_SUCCESS) {
+ ret = wolfSSL_X509_set_notBefore(x509, asnBefore);
+ }
+
+ if (asnBefore != NULL) {
+ wolfSSL_ASN1_TIME_free(asnBefore);
+ }
+
+ return ret;
+#else
+ (void)jenv;
+ (void)jcl;
+ (void)x509Ptr;
+ (void)notBefore;
+ return (jint)NOT_COMPILED_IN;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1notAfter
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr, jlong notAfter)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
+ (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+
+ WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
+ WOLFSSL_ASN1_TIME* asnAfter = NULL;
+ int ret = WOLFSSL_SUCCESS;
+ time_t notAfterTime = (time_t)(long)notAfter;
+ (void)jcl;
+
+ if (jenv == NULL || x509 == NULL) {
+ return WOLFSSL_FAILURE;
+ }
+
+ /* set time_t value into WOLFSSL_ASN1_TIME struct, no adjustment */
+ asnAfter = wolfSSL_ASN1_TIME_adj(NULL, notAfterTime, 0, 0);
+ if (asnAfter == NULL) {
+ ret = WOLFSSL_FAILURE;
+ }
+
+ if (ret == WOLFSSL_SUCCESS) {
+ ret = wolfSSL_X509_set_notAfter(x509, asnAfter);
+ }
+
+ if (asnAfter != NULL) {
+ wolfSSL_ASN1_TIME_free(asnAfter);
+ }
+
+ return ret;
+#else
+ (void)jenv;
+ (void)jcl;
+ (void)x509Ptr;
+ (void)notAfter;
+ return (jint)NOT_COMPILED_IN;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1serialNumber
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr, jbyteArray serialBytes)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
+ (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+ WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
+ WOLFSSL_ASN1_INTEGER* serial = NULL;
+ byte* serialBuf = NULL;
+ int serialSz = 0;
+ int ret = WOLFSSL_SUCCESS;
+ (void)jcl;
+
+ if (jenv == NULL || x509 == NULL) {
+ return WOLFSSL_FAILURE;
+ }
+
+ serialBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, serialBytes, NULL);
+ serialSz = (*jenv)->GetArrayLength(jenv, serialBytes);
+
+ if (serialBuf == NULL || serialSz == 0) {
+ ret = WOLFSSL_FAILURE;
+ }
+
+ if (ret == WOLFSSL_SUCCESS) {
+ serial = wolfSSL_ASN1_INTEGER_new();
+ if (serial == NULL) {
+ ret = WOLFSSL_FAILURE;
+ }
+ else {
+ serial->data[0] = ASN_INTEGER;
+ serial->data[1] = serialSz;
+ XMEMCPY(&serial->data[2], serialBuf, serialSz);
+ serial->length = serialSz + 2;
+ }
+ }
+
+ if (ret == WOLFSSL_SUCCESS) {
+ /* copies contents of ASN1_INTEGER, we can free below */
+ ret = wolfSSL_X509_set_serialNumber(x509, serial);
+ }
+
+ if (serial != NULL) {
+ wolfSSL_ASN1_INTEGER_free(serial);
+ }
+
+ (*jenv)->ReleaseByteArrayElements(jenv, serialBytes, (jbyte*)serialBuf,
+ JNI_ABORT);
+
+ return ret;
+#else
+ (void)jenv;
+ (void)jcl;
+ (void)x509Ptr;
+ (void)serialBytes;
+ return (jint)NOT_COMPILED_IN;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1sign
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr, jint keyType, jbyteArray fileBytes, jint fileFormat, jstring digestAlg)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
+ (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \
+ defined(WOLFSSL_CERT_GEN)
+ WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
+
+ byte* fileBuf = NULL;
+ int fileSz = 0;
+ byte* derBuf = NULL;
+ 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;
+ }
+
+ fileBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, fileBytes, NULL);
+ fileSz = (*jenv)->GetArrayLength(jenv, fileBytes);
+
+ if (fileBuf == NULL || fileSz == 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 = 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) {
+ rsaPrivBuf = derBuf;
+
+ priv = wolfSSL_d2i_PrivateKey((int)keyType, NULL,
+ (const unsigned char**)&rsaPrivBuf, derSz);
+ if (priv == NULL) {
+ ret = WOLFSSL_FAILURE;
+ }
+ }
+
+ /* set version to v3 (only supported currently */
+ if (ret == WOLFSSL_SUCCESS) {
+ ret = wolfSSL_X509_set_version(x509, 2L);
+ }
+
+ /* sign WOLFSSL_X509 with WOLFSSL_EVP_PKEY, returns size of signature
+ * on success or negative on error */
+ if (ret == WOLFSSL_SUCCESS) {
+ ret = wolfSSL_X509_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, fileBytes, (jbyte*)fileBuf,
+ JNI_ABORT);
+ (*jenv)->ReleaseStringUTFChars(jenv, digestAlg, mdName);
+
+ return (jint)ret;
+#else
+ (void)jenv;
+ (void)jcl;
+ (void)x509Ptr;
+ (void)keyType;
+ (void)fileBytes;
+ (void)fileFormat;
+ (void)digestAlg;
+ return (jint)NOT_COMPILED_IN;
+#endif
+}
+
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1load_1certificate_1buffer
(JNIEnv* jenv, jclass jcl, jbyteArray in, jint format)
{
@@ -139,6 +805,83 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1der
return derArr;
}
+JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1pem
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr)
+{
+#ifdef WOLFSSL_DER_TO_PEM
+ int sz = 0;
+ const byte* der = NULL;
+ byte* pem = NULL;
+ int pemSz = 0;
+ jbyteArray pemArr = NULL;
+ jclass excClass = NULL;
+ WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
+
+ if (jenv == NULL || x509 == NULL) {
+ return NULL;
+ }
+
+ der = wolfSSL_X509_get_der(x509, &sz);
+ if (der == NULL || sz == 0) {
+ return NULL;
+ }
+
+ pemSz = wc_DerToPem(der, sz, NULL, 0, CERT_TYPE);
+ if (pemSz < 0) {
+ return NULL;
+ }
+
+ pem = (byte*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (pem == NULL) {
+ return NULL;
+ }
+ XMEMSET(pem, 0, pemSz);
+
+ pemSz = wc_DerToPem(der, sz, pem, pemSz, CERT_TYPE);
+ if (pemSz < 0) {
+ XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ return NULL;
+ }
+
+ pemArr = (*jenv)->NewByteArray(jenv, pemSz);
+ if (pemArr == NULL) {
+ (*jenv)->ThrowNew(jenv, jcl,
+ "Failed to create byte array in native X509_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);
+ (*jenv)->ThrowNew(jenv, excClass,
+ "Failed to set byte region in native X509_get_pem");
+ XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ return NULL;
+ }
+
+ XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+ return pemArr;
+#else
+ (void)jenv;
+ (void)jcl;
+ (void)x509Ptr;
+ return NULL;
+#endif
+}
+
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1tbs
(JNIEnv* jenv, jclass jcl, jlong x509Ptr)
{
@@ -541,6 +1284,33 @@ JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1issuer_
return NULL;
}
+JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1issuer_1name_1ptr
+ (JNIEnv* jenv, jclass jcl, jlong x509Ptr)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
+ (defined(OPENSSL_EXTRA_X509_SMALL) || defined(KEEP_PEER_CERT) || \
+ defined(SESSION_CERTS))
+ WOLFSSL_X509* x509 = (WOLFSSL_X509*)(uintptr_t)x509Ptr;
+ WOLFSSL_X509_NAME* name = NULL;
+
+ if (jenv == NULL || x509 == NULL) {
+ return 0;
+ }
+
+ name = wolfSSL_X509_get_issuer_name(x509);
+ if (name == NULL) {
+ return 0;
+ }
+
+ return (jlong)(uintptr_t)name;
+#else
+ (void)jenv;
+ (void)jcl;
+ (void)x509Ptr;
+ return (jlong)0;
+#endif
+}
+
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1pubkey
(JNIEnv* jenv, jclass jcl, jlong x509Ptr)
{
diff --git a/native/com_wolfssl_WolfSSLCertificate.h b/native/com_wolfssl_WolfSSLCertificate.h
index ac0ffe3..494c911 100644
--- a/native/com_wolfssl_WolfSSLCertificate.h
+++ b/native/com_wolfssl_WolfSSLCertificate.h
@@ -7,6 +7,10 @@
#ifdef __cplusplus
extern "C" {
#endif
+#undef com_wolfssl_WolfSSLCertificate_EVP_PKEY_RSA
+#define com_wolfssl_WolfSSLCertificate_EVP_PKEY_RSA 16L
+#undef com_wolfssl_WolfSSLCertificate_EVP_PKEY_EC
+#define com_wolfssl_WolfSSLCertificate_EVP_PKEY_EC 18L
/*
* Class: com_wolfssl_WolfSSLCertificate
* Method: X509_get_der
@@ -15,6 +19,14 @@ extern "C" {
JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1der
(JNIEnv *, jclass, jlong);
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_get_pem
+ * Signature: (J)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1pem
+ (JNIEnv *, jclass, jlong);
+
/*
* Class: com_wolfssl_WolfSSLCertificate
* Method: X509_get_tbs
@@ -119,6 +131,14 @@ JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1subject
JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1issuer_1name
(JNIEnv *, jclass, jlong);
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_get_issuer_name_ptr
+ * Signature: (J)J
+ */
+JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1get_1issuer_1name_1ptr
+ (JNIEnv *, jclass, jlong);
+
/*
* Class: com_wolfssl_WolfSSLCertificate
* Method: X509_get_pubkey
@@ -199,6 +219,102 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1load_1certific
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1load_1certificate_1file
(JNIEnv *, jclass, jstring, jint);
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_new
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1new
+ (JNIEnv *, jclass);
+
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_set_subject_name
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1subject_1name
+ (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_set_issuer_name
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1issuer_1name
+ (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_set_issuer_name_from_der
+ * Signature: (J[B)I
+ */
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1issuer_1name_1from_1der
+ (JNIEnv *, jclass, jlong, jbyteArray);
+
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_set_pubkey_native_open
+ * Signature: (JI[BI)I
+ */
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1pubkey_1native_1open
+ (JNIEnv *, jclass, jlong, jint, jbyteArray, jint);
+
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_add_altname
+ * Signature: (JLjava/lang/String;I)I
+ */
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1altname
+ (JNIEnv *, jclass, jlong, jstring, jint);
+
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_add_ext_via_nconf_nid
+ * Signature: (JILjava/lang/String;Z)I
+ */
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1ext_1via_1nconf_1nid
+ (JNIEnv *, jclass, jlong, jint, jstring, jboolean);
+
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_add_ext_via_set_object_boolean
+ * Signature: (JIZZ)I
+ */
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1add_1ext_1via_1set_1object_1boolean
+ (JNIEnv *, jclass, jlong, jint, jboolean, jboolean);
+
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_set_notBefore
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1notBefore
+ (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_set_notAfter
+ * Signature: (JJ)I
+ */
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1notAfter
+ (JNIEnv *, jclass, jlong, jlong);
+
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_set_serialNumber
+ * Signature: (J[B)I
+ */
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1set_1serialNumber
+ (JNIEnv *, jclass, jlong, jbyteArray);
+
+/*
+ * Class: com_wolfssl_WolfSSLCertificate
+ * Method: X509_sign
+ * Signature: (JI[BILjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1sign
+ (JNIEnv *, jclass, jlong, jint, jbyteArray, jint, jstring);
+
#ifdef __cplusplus
}
#endif
diff --git a/native/com_wolfssl_WolfSSLX509Name.c b/native/com_wolfssl_WolfSSLX509Name.c
new file mode 100644
index 0000000..4d4906c
--- /dev/null
+++ b/native/com_wolfssl_WolfSSLX509Name.c
@@ -0,0 +1,126 @@
+/* com_wolfssl_WolfSSLX509Name.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
+#include
+
+#ifdef WOLFSSL_USER_SETTINGS
+ #include
+#else
+ #include
+#endif
+
+#include
+
+#include "com_wolfssl_globals.h"
+#include "com_wolfssl_WolfSSLX509Name.h"
+
+JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLX509Name_X509_1NAME_1new
+ (JNIEnv* jenv, jclass jcl)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
+ (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+ WOLFSSL_X509_NAME* x509Name = NULL;
+ (void)jcl;
+
+ if (jenv == NULL) {
+ return 0;
+ }
+
+ x509Name = wolfSSL_X509_NAME_new();
+ if (x509Name == NULL) {
+ return 0;
+ }
+
+ return (jlong)(uintptr_t)x509Name;
+#else
+ (void)jenv;
+ (void)jcl;
+ return 0;
+#endif
+}
+
+JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLX509Name_X509_1NAME_1free
+ (JNIEnv* jenv, jclass jcl, jlong x509NamePtr)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
+ (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+ WOLFSSL_X509_NAME* ptr = (WOLFSSL_X509_NAME*)(uintptr_t)x509NamePtr;
+ (void)jcl;
+
+ if (jenv == NULL || ptr == NULL) {
+ return;
+ }
+
+ wolfSSL_X509_NAME_free(ptr);
+#else
+ (void)jenv;
+ (void)jcl;
+ (void)x509NamePtr;
+#endif
+}
+
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLX509Name_X509_1NAME_1add_1entry_1by_1txt
+ (JNIEnv* jenv, jclass jcl, jlong x509NamePtr, jstring fieldStr, jint type,
+ jbyteArray entryArr, jint entryLen, jint loc, jint set)
+{
+#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && \
+ (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL))
+ WOLFSSL_X509_NAME* ptr = (WOLFSSL_X509_NAME*)(uintptr_t)x509NamePtr;
+ const char* field = NULL;
+ unsigned char* entry = NULL;
+ int ret = WOLFSSL_FAILURE;
+ int len = 0;
+ (void)jcl;
+ (void)entryLen;
+
+ if (jenv == NULL) {
+ return ret;
+ }
+
+ field = (*jenv)->GetStringUTFChars(jenv, fieldStr, 0);
+ entry = (unsigned char*)(*jenv)->GetByteArrayElements(jenv, entryArr, NULL);
+ len = (*jenv)->GetArrayLength(jenv, entryArr);
+
+ if (entry != NULL && len > 0 && field != NULL) {
+
+ ret = wolfSSL_X509_NAME_add_entry_by_txt(ptr, field, (int)type,
+ entry, len, (int)loc, (int)set);
+ }
+
+ (*jenv)->ReleaseByteArrayElements(jenv, entryArr, (jbyte*)entry, JNI_ABORT);
+ (*jenv)->ReleaseStringUTFChars(jenv, fieldStr, field);
+
+ return (jint)ret;
+#else
+ (void)jenv;
+ (void)jcl;
+ (void)x509NamePtr;
+ (void)fieldStr;
+ (void)type;
+ (void)entryArr;
+ (void)entryLen;
+ (void)loc;
+ (void)set;
+ return (jint)NOT_COMPILED_IN;
+#endif
+}
+
diff --git a/native/com_wolfssl_WolfSSLX509Name.h b/native/com_wolfssl_WolfSSLX509Name.h
new file mode 100644
index 0000000..0fde184
--- /dev/null
+++ b/native/com_wolfssl_WolfSSLX509Name.h
@@ -0,0 +1,39 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include
+/* Header for class com_wolfssl_WolfSSLX509Name */
+
+#ifndef _Included_com_wolfssl_WolfSSLX509Name
+#define _Included_com_wolfssl_WolfSSLX509Name
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef com_wolfssl_WolfSSLX509Name_MBSTRING_UTF8
+#define com_wolfssl_WolfSSLX509Name_MBSTRING_UTF8 256L
+/*
+ * Class: com_wolfssl_WolfSSLX509Name
+ * Method: X509_NAME_new
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLX509Name_X509_1NAME_1new
+ (JNIEnv *, jclass);
+
+/*
+ * Class: com_wolfssl_WolfSSLX509Name
+ * Method: X509_NAME_free
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLX509Name_X509_1NAME_1free
+ (JNIEnv *, jclass, jlong);
+
+/*
+ * Class: com_wolfssl_WolfSSLX509Name
+ * Method: X509_NAME_add_entry_by_txt
+ * Signature: (JLjava/lang/String;I[BIII)I
+ */
+JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLX509Name_X509_1NAME_1add_1entry_1by_1txt
+ (JNIEnv *, jclass, jlong, jstring, jint, jbyteArray, jint, jint, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/java/com/wolfssl/WolfSSL.java b/src/java/com/wolfssl/WolfSSL.java
index 9099c41..e3ba852 100644
--- a/src/java/com/wolfssl/WolfSSL.java
+++ b/src/java/com/wolfssl/WolfSSL.java
@@ -346,6 +346,20 @@ public class WolfSSL {
/** Ed25519 key type */
public static final int ED25519k = 256;
+ /* GeneralName types. Match native values in asn.h */
+ public static final int ASN_OTHER_TYPE = 0x00;
+ public static final int ASN_RFC822_TYPE = 0x01;
+ public static final int ASN_DNS_TYPE = 0x02;
+ public static final int ASN_DIR_TYPE = 0x04;
+ public static final int ASN_URI_TYPE = 0x06;
+ public static final int ASN_IP_TYPE = 0x07;
+
+ /* NIDs, from native asn.h */
+ public static final int NID_key_usage = 129;
+ public static final int NID_subject_alt_name = 131;
+ public static final int NID_basic_constraints = 133;
+ public static final int NID_ext_key_usage = 151;
+
/* is this object active, or has it been cleaned up? */
private boolean active = false;
@@ -1048,6 +1062,15 @@ public class WolfSSL {
*/
public static native int getHmacMaxSize();
+ /**
+ * Return the wolfSSL library vesrion number in hex.
+ *
+ * Wrapper around native wolfSSL_lib_version_hex()
+ *
+ * @return wolfSSL native library version hex value
+ */
+ public static native long getLibVersionHex();
+
/**
* Returns the enabled cipher suites for native wolfSSL.
*
diff --git a/src/java/com/wolfssl/WolfSSLCertificate.java b/src/java/com/wolfssl/WolfSSLCertificate.java
index fa9efab..e0aab09 100644
--- a/src/java/com/wolfssl/WolfSSLCertificate.java
+++ b/src/java/com/wolfssl/WolfSSLCertificate.java
@@ -23,7 +23,9 @@ package com.wolfssl;
import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
+import java.io.File;
import java.nio.charset.Charset;
+import java.nio.file.Files;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -33,9 +35,16 @@ import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+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;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
+import java.security.cert.CertificateEncodingException;
/**
* WolfSSLCertificate class, wraps native wolfSSL WOLFSSL_X509 functionality.
@@ -52,10 +61,19 @@ public class WolfSSLCertificate {
/* lock around active state */
private final Object stateLock = new Object();
+ /* lock around native WOLFSSL_X509 pointer use */
+ private final Object x509Lock = new Object();
+
/* cache alt names once retrieved once */
private Collection> altNames = null;
+ /* Public key types used for certificate generation, 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;
+
static native byte[] X509_get_der(long x509);
+ static native byte[] X509_get_pem(long x509);
static native byte[] X509_get_tbs(long x509);
static native void X509_free(long x509);
static native int X509_get_serial_number(long x509, byte[] out);
@@ -69,6 +87,7 @@ public class WolfSSLCertificate {
static native int X509_get_isCA(long x509);
static native String X509_get_subject_name(long x509);
static native String X509_get_issuer_name(long x509);
+ static native long X509_get_issuer_name_ptr(long x509);
static native byte[] X509_get_pubkey(long x509);
static native String X509_get_pubkey_type(long x509);
static native int X509_get_pathLength(long x509);
@@ -80,6 +99,45 @@ public class WolfSSLCertificate {
static native long X509_load_certificate_buffer(byte[] buf, int format);
static native long X509_load_certificate_file(String path, int format);
+ /* native functions used for X509v3 certificate generation */
+ static native long X509_new();
+ static native int X509_set_subject_name(long x509Ptr, long x509NamePtr);
+ static native int X509_set_issuer_name(long x509Ptr, long x509NamePtr);
+ static native int X509_set_issuer_name_from_der(long x509Ptr, byte[] certDer);
+ static native int X509_set_pubkey_native_open(long x509Ptr, int keyType,
+ byte[] fileBytes, int format);
+ static native int X509_add_altname(long x509Ptr, String name, int type);
+ 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);
+ static native int X509_set_notBefore(long x509Ptr, long timeSecs);
+ static native int X509_set_notAfter(long x509Ptr, long timeSecs);
+ static native int X509_set_serialNumber(long x509Ptr, byte[] serialBytes);
+ static native int X509_sign(long x509Ptr, int evpKeyType, byte[] keyBytes,
+ int format, String digestAlg);
+
+ /**
+ * Create new empty WolfSSLCertificate object, for use with X509v3
+ * certificate generation.
+ *
+ * @throws WolfSSLException if native API call fails.
+ */
+ public WolfSSLCertificate() throws WolfSSLException {
+
+ x509Ptr = X509_new();
+ if (x509Ptr == 0) {
+ throw new WolfSSLException("Failed to create WolfSSLCertificate");
+ }
+
+ /* x509Ptr has been allocated natively, mark as owned */
+ this.weOwnX509Ptr = true;
+
+ synchronized (stateLock) {
+ this.active = true;
+ }
+ }
+
/**
* Create new WolfSSLCertificate from DER-encoded byte array.
*
@@ -236,60 +294,761 @@ public class WolfSSLCertificate {
}
}
+ /**
+ * Verifies that the current WolfSSLCertificate object is active.
+ *
+ * @throws IllegalStateException if object has been freed
+ */
+ private void confirmObjectIsActive()
+ throws IllegalStateException {
+
+ synchronized (stateLock) {
+ if (this.active == false) {
+ throw new IllegalStateException(
+ "WolfSSLCertificate object has been freed");
+ }
+ }
+ }
+
+ /**
+ * Protected method to be used by objects of this class to get
+ * internal WOLFSSL_X509 pointer.
+ *
+ * @return internal WOLFSSL_X509 pointer value
+ * @throws IllegalStateException if object has been freed
+ */
+ protected long getX509Ptr() throws IllegalStateException {
+
+ confirmObjectIsActive();
+
+ return this.x509Ptr;
+ }
+
+ /**
+ * Set the Subject Name to be used with this WolfSSLCertificate.
+ * 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 WolfSSLCertificate for cert generation.
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
+ * @throws WolfSSLException if native JNI error occurs.
+ */
+ public void setSubjectName(WolfSSLX509Name name)
+ throws IllegalStateException, WolfSSLException {
+
+ int ret;
+
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ /* TODO somehow lock WolfSSLX509Name object while using pointer? */
+ ret = X509_set_subject_name(this.x509Ptr,
+ name.getNativeX509NamePtr());
+ }
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException("Error setting subject name " +
+ "(ret: " + ret + ")");
+ }
+ }
+
+ /**
+ * Set the Issuer Name to be used with this WolfSSLCertificate.
+ * 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
+ * Issuer Name of WolfSSLCertificate for cert generation.
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
+ * @throws WolfSSLException if native JNI error occurs.
+ */
+ public void setIssuerName(WolfSSLX509Name name)
+ throws IllegalStateException, WolfSSLException {
+
+ int ret;
+
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ /* TODO somehow lock WolfSSLX509Name object while using pointer? */
+ ret = X509_set_issuer_name(this.x509Ptr,
+ name.getNativeX509NamePtr());
+ }
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException("Error setting issuer name " +
+ "(ret: " + ret + ")");
+ }
+ }
+
+ /**
+ * Set the Issuer Name to be used with this WolfSSLCertificate.
+ * This method copies the issuer name from the existing populated
+ * WolfSSLCertificate object, which would commonly be initialized
+ * from a CA certificate file or byte array.
+ *
+ * @param cert Initialized and populated WolfSSLCertificate to be set into
+ * Issuer Name of this WolfSSLCertificate for cert generation.
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
+ * @throws WolfSSLException if native JNI error occurs.
+ */
+ public void setIssuerName(WolfSSLCertificate cert)
+ throws IllegalStateException, WolfSSLException {
+
+ int ret;
+ long x509CertPtr = 0;
+ long x509NamePtr = 0;
+
+ confirmObjectIsActive();
+
+ x509NamePtr = X509_get_issuer_name_ptr(cert.getX509Ptr());
+ if (x509NamePtr == 0) {
+ throw new WolfSSLException("Error getting issuer name from " +
+ "WolfSSLCertificate");
+ }
+
+ synchronized (x509Lock) {
+ /* TODO somehow lock WolfSSLX509Name object while using pointer? */
+ ret = X509_set_issuer_name(this.x509Ptr, x509NamePtr);
+ }
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException("Error setting issuer name " +
+ "(ret: " + ret + ")");
+ }
+ }
+
+ /**
+ * Set the Issuer Name to be used with this WolfSSLCertificate.
+ * This method copies the issuer name from the existing populated
+ * X509Certificate object.
+ *
+ * @param cert Initialized and populated X509Certificate to be used to set
+ * Issuer Name of this WolfSSLCertificate for cert generation.
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
+ * @throws WolfSSLException if native JNI error occurs.
+ * @throws CertificateEncodingException if error occurs while parsing
+ * X509Certificate
+ */
+ public void setIssuerName(X509Certificate cert)
+ throws IllegalStateException, WolfSSLException,
+ CertificateEncodingException {
+
+ int ret;
+ byte[] certDer = null;
+
+ confirmObjectIsActive();
+
+ /* Get DER encoding of certificate */
+ certDer = cert.getEncoded();
+
+ synchronized (x509Lock) {
+ ret = X509_set_issuer_name_from_der(this.x509Ptr, certDer);
+ }
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException("Error setting issuer name " +
+ "(ret: " + ret + ")");
+ }
+ }
+
+ /**
+ * Set public key for this WolfSSLCertificate, used when generating
+ * X509v3 certificates.
+ *
+ * @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 WolfSSLCertificate 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 WolfSSLCertificate, used when generating
+ * X509v3 certificates.
+ *
+ * @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 WolfSSLCertificate 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 (x509Lock) {
+ ret = X509_set_pubkey_native_open(this.x509Ptr, evpKeyType,
+ key, format);
+ }
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException(
+ "Error setting public key into native WOLFSSL_X509 " +
+ "(ret: " + ret + ")");
+ }
+ }
+
+ /**
+ * Set public key for this WolfSSLCertificate, used when generating
+ * X509v3 certificates.
+ *
+ * @param key PublicKey object containing public key to be used when
+ * generating X509v3 certificate.
+ *
+ * @throws IllegalStateException if WolfSSLCertificate 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);
+ }
+
+ /**
+ * Sets the serial number for this WolfSSLCertificate, used when
+ * generating X509v3 certificates.
+ *
+ * @param serial BigInteger holding serial number for generated cert
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
+ * @throws WolfSSLException if invalid arguments or native JNI error occurs.
+ */
+ public void setSerialNumber(BigInteger serial)
+ throws IllegalStateException, WolfSSLException {
+
+ int ret = 0;
+ byte[] serialBytes = null;
+
+ confirmObjectIsActive();
+
+ if (serial == null) {
+ throw new WolfSSLException("Input BigInteger is null");
+ }
+
+ serialBytes = serial.toByteArray();
+ if (serialBytes == null || serialBytes.length == 0) {
+ throw new WolfSSLException("BigInteger.toByteArray() " +
+ "is null or 0 length");
+ }
+
+ synchronized (x509Lock) {
+ ret = X509_set_serialNumber(this.x509Ptr, serialBytes);
+ }
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException(
+ "Error setting serial number into native WOLFSSL_X509 " +
+ "(ret: " + ret + ")");
+ }
+ }
+
+ /**
+ * Sets the notBefore date for this WolfSSLCertificate, used when
+ * generating X509v3 certificates.
+ *
+ * @param notBefore Date object representing notBefore date/time to set
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
+ * @throws WolfSSLException if invalid arguments or native JNI error occurs.
+ */
+ public void setNotBefore(Date notBefore)
+ throws IllegalStateException, WolfSSLException {
+
+ int ret = 0;
+
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ ret = X509_set_notBefore(this.x509Ptr, notBefore.getTime() / 1000);
+ }
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException(
+ "Error setting notBefore date into native WOLFSSL_X509 " +
+ "(ret: " + ret + ")");
+ }
+ }
+
+ /**
+ * Sets the notAfter date for this WolfSSLCertificate, used when
+ * generating X509v3 certificates.
+ *
+ * @param notAfter Date object representing notAfter date/time to set
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
+ * @throws WolfSSLException if invalid arguments or native JNI error occurs.
+ */
+ public void setNotAfter(Date notAfter)
+ throws IllegalStateException, WolfSSLException {
+
+ int ret = 0;
+
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ ret = X509_set_notAfter(this.x509Ptr, notAfter.getTime() / 1000);
+ }
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException(
+ "Error setting notAfter date into native WOLFSSL_X509 " +
+ "(ret: " + ret + ")");
+ }
+ }
+
+ /**
+ * Add subject alternative name for this WolfSSLCertificate, used when
+ * generating X509v3 certificates.
+ *
+ * @param name String value of subject alternative name to set
+ * @param type Type of subject alt name entry, must be one of:
+ * WolfSSL.ASN_OTHER_TYPE, WolfSSL.ASN_RFC822_TYPE,
+ * WolfSSL.ASN_DNS_TYPE, WolfSSL.ASN_DIR_TYPE, WolfSSL.ASN_URI_TYPE,
+ * WolfSSL.ASN_IP_TYPE
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
+ * @throws WolfSSLException if invalid arguments or native JNI error occurs.
+ */
+ public void addAltName(String name, int type)
+ throws IllegalStateException, WolfSSLException {
+
+ int ret = 0;
+
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ ret = X509_add_altname(this.x509Ptr, name, type);
+ }
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException(
+ "Error setting altName into native WOLFSSL_X509 " +
+ "(ret: " + ret + ")");
+ }
+ }
+
+ /**
+ * Add an extension to a WOLFSSL_X509 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_subject_alt_name
+ * @param value String value of extension to set
+ * @param isCritical Boolean flag indicating if this extension is
+ * critical
+ *
+ * @throws IllegalStateException if WolfSSLCertificate 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 (x509Lock) {
+ ret = X509_add_ext_via_nconf_nid(this.x509Ptr, 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 WOLFSSL_X509 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_key_usage
+ * WolfSSL.NID_subject_alt_name
+ * @param value Boolean value of extension (true/false)
+ * @param isCritical Boolean flag indicating if this extension is
+ * critical
+ *
+ * @throws IllegalStateException if WolfSSLCertificate 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 (x509Lock) {
+ ret = X509_add_ext_via_set_object_boolean(
+ this.x509Ptr, nid, value, isCritical);
+ }
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException(
+ "Error setting extension into native WOLFSSL_X509 " +
+ "(ret: " + ret + ")");
+ }
+ }
+
+ /**
+ * Sign certificate 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 WolfSSLCertificate has been freed.
+ * @throws IOException on error opening input file
+ * @throws WolfSSLException if invalid arguments or native JNI error occurs.
+ */
+ public void signCert(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);
+ }
+
+ signCert(Files.readAllBytes(keyFile.toPath()), keyType, format,
+ digestAlg);
+ }
+
+ /**
+ * Sign certificate 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 WolfSSLCertificate has been freed.
+ * @throws WolfSSLException if invalid arguments or native JNI error occurs.
+ */
+ public void signCert(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 (x509Lock) {
+ ret = X509_sign(this.x509Ptr, evpKeyType, key, format, digestAlg);
+ }
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException(
+ "Error signing native WOLFSSL_X509 " +
+ "(ret: " + ret + ")");
+ }
+ }
+
+ /**
+ * Sign certificate 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 WolfSSLCertificate has been freed.
+ * @throws WolfSSLException if invalid arguments or native JNI error occurs.
+ */
+ public void signCert(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 (x509Lock) {
+ ret = X509_sign(this.x509Ptr, evpKeyType, encodedKey,
+ WolfSSL.SSL_FILETYPE_ASN1, digestAlg);
+ }
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException(
+ "Error signing native WOLFSSL_X509 " +
+ "(ret: " + ret + ")");
+ }
+ }
+
/**
* Get ASN.1/DER encoding of this X.509 certificate
*
* @return DER encoded array of certificate or null if not available.
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
+ * @throws WolfSSLJNIException if native JNI operation fails
*/
- public byte[] getDer() {
+ public byte[] getDer() throws IllegalStateException, WolfSSLJNIException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_get_der(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_der(this.x509Ptr);
}
+ }
- return null;
+ /**
+ * Get PEM encoding of this X.509 certificate
+ *
+ * @return PEM encoded array of certificate or null if not available.
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
+ * @throws WolfSSLJNIException if native JNI operation fails
+ */
+ public byte[] getPem() throws IllegalStateException, WolfSSLJNIException {
+
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_pem(this.x509Ptr);
+ }
}
/**
* Get buffer that is To Be Signed (Tbs)
*
* @return byte array to be signed
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public byte[] getTbs() {
+ public byte[] getTbs() throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_get_tbs(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_tbs(this.x509Ptr);
}
-
- return null;
}
/**
* Get X.509 serial number as BigInteger
*
* @return serial number as BigInteger, or null if not available
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public BigInteger getSerial() {
+ public BigInteger getSerial() throws IllegalStateException {
+
byte[] out = new byte[32];
int sz;
- synchronized (stateLock) {
- if (this.active == false) {
- return null;
- }
+ confirmObjectIsActive();
- sz = X509_get_serial_number(this.x509Ptr, out);
- if (sz <= 0) {
- return null;
- }
- else {
- byte[] serial = Arrays.copyOf(out, sz);
- return new BigInteger(serial);
- }
+ synchronized (x509Lock) {
+ sz = X509_get_serial_number(this.x509Ptr, out);
+ }
+ if (sz <= 0) {
+ return null;
+ }
+ else {
+ byte[] serial = Arrays.copyOf(out, sz);
+ return new BigInteger(serial);
}
}
@@ -297,26 +1056,28 @@ public class WolfSSLCertificate {
* Get X.509 validity notBefore date
*
* @return notBefore date as Date object, or null if not available
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public Date notBefore() {
+ public Date notBefore() throws IllegalStateException {
+
String nb;
- synchronized (stateLock) {
- if (this.active == false) {
- return null;
- }
+ confirmObjectIsActive();
+ synchronized (x509Lock) {
nb = X509_notBefore(this.x509Ptr);
- if (nb != null) {
- SimpleDateFormat format =
- new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz");
- try {
- return format.parse(nb);
- } catch (ParseException ex) {
- /* error case parsing date */
- }
+ }
+ if (nb != null) {
+ SimpleDateFormat format =
+ new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz");
+ try {
+ return format.parse(nb);
+ } catch (ParseException ex) {
+ /* error case parsing date */
}
}
+
return null;
}
@@ -324,26 +1085,28 @@ public class WolfSSLCertificate {
* Get X.509 validity notAfter date
*
* @return notAfter date as Date object, or null if not available
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public Date notAfter() {
+ public Date notAfter() throws IllegalStateException {
+
String nb;
- synchronized (stateLock) {
- if (this.active == false) {
- return null;
- }
+ confirmObjectIsActive();
+ synchronized (x509Lock) {
nb = X509_notAfter(this.x509Ptr);
- if (nb != null) {
- SimpleDateFormat format =
- new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz");
- try {
- return format.parse(nb);
- } catch (ParseException ex) {
- /* error case parsing date */
- }
+ }
+ if (nb != null) {
+ SimpleDateFormat format =
+ new SimpleDateFormat("MMM dd HH:mm:ss yyyy zzz");
+ try {
+ return format.parse(nb);
+ } catch (ParseException ex) {
+ /* error case parsing date */
}
}
+
return null;
}
@@ -351,160 +1114,160 @@ public class WolfSSLCertificate {
* Get X.509 version
*
* @return version of X.509 certificate
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public int getVersion() {
+ public int getVersion() throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_version(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_version(this.x509Ptr);
}
-
- return 0;
}
/**
* Get signature from X.509 certificate
*
* @return byte array with signature from X.509 certificate, or null
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public byte[] getSignature() {
+ public byte[] getSignature() throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_get_signature(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_signature(this.x509Ptr);
}
-
- return null;
}
/**
* Get signature type from X.509 certificate
*
* @return signature type String, or null
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public String getSignatureType() {
+ public String getSignatureType() throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_get_signature_type(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_signature_type(this.x509Ptr);
}
-
- return null;
}
/**
* Get X.509 signature algorithm OID
*
* @return algorithm OID of signature, or null
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public String getSignatureOID() {
+ public String getSignatureOID() throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_get_signature_OID(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_signature_OID(this.x509Ptr);
}
-
- return null;
}
/**
* Get public key from X.509 certificate
*
* @return certificate public key, byte array. Or null.
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public byte[] getPubkey() {
+ public byte[] getPubkey() throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_get_pubkey(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_pubkey(this.x509Ptr);
}
-
- return null;
}
/**
* Get public key type of certificate
*
* @return public key type String, or null
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public String getPubkeyType() {
+ public String getPubkeyType() throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_get_pubkey_type(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_pubkey_type(this.x509Ptr);
}
-
- return null;
}
/**
* Get certificate isCA value
*
* @return X.509 isCA value
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public int isCA() {
+ public int isCA() throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_get_isCA(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_isCA(this.x509Ptr);
}
-
- return 0;
}
/**
* Get certificate path length
*
* @return path length, or -1 if not set
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public int getPathLen() {
+ public int getPathLen() throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_get_pathLength(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_pathLength(this.x509Ptr);
}
-
- return 0;
}
/**
* Get certificate Subject
*
* @return X.509 Subject String, or null
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public String getSubject() {
+ public String getSubject() throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_get_subject_name(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_subject_name(this.x509Ptr);
}
-
- return null;
}
/**
* Get certificate Issuer
*
* @return X.509 Issuer String, or null
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public String getIssuer() {
+ public String getIssuer() throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_get_issuer_name(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_issuer_name(this.x509Ptr);
}
-
- return null;
}
/**
@@ -514,19 +1277,21 @@ public class WolfSSLCertificate {
* @param pubKeySz size of public key array, bytes
*
* @return true if verified, otherwise false
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public boolean verify(byte[] pubKey, int pubKeySz) {
+ public boolean verify(byte[] pubKey, int pubKeySz)
+ throws IllegalStateException {
+
int ret;
- synchronized (stateLock) {
- if (this.active == false) {
- return false;
- }
+ confirmObjectIsActive();
+ synchronized (x509Lock) {
ret = X509_verify(this.x509Ptr, pubKey, pubKeySz);
- if (ret == WolfSSL.SSL_SUCCESS) {
- return true;
- }
+ }
+ if (ret == WolfSSL.SSL_SUCCESS) {
+ return true;
}
return false;
@@ -547,16 +1312,16 @@ public class WolfSSLCertificate {
* [8] = KEYUSE_DECIPHER_ONLY
*
* @return arrray of key usages set for certificate, or null
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public boolean[] getKeyUsage() {
+ public boolean[] getKeyUsage() throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == true) {
- return X509_get_key_usage(this.x509Ptr);
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
+ return X509_get_key_usage(this.x509Ptr);
}
-
- return null;
}
/**
@@ -565,13 +1330,18 @@ public class WolfSSLCertificate {
* @param oid OID value of extension to retreive value for
*
* @return DER encoded extension value, or null
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public byte[] getExtension(String oid) {
+ public byte[] getExtension(String oid) throws IllegalStateException {
- synchronized (stateLock) {
- if (oid == null || this.active == false) {
- return null;
- }
+ confirmObjectIsActive();
+
+ if (oid == null) {
+ return null;
+ }
+
+ synchronized (x509Lock) {
return X509_get_extension(this.x509Ptr, oid);
}
}
@@ -585,13 +1355,14 @@ public class WolfSSLCertificate {
* 2 if extension OID is set and is critical,
* 0 if not set,
* otherwise negative value on error
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public int getExtensionSet(String oid) {
+ public int getExtensionSet(String oid) throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == false) {
- return 0;
- }
+ confirmObjectIsActive();
+
+ synchronized (x509Lock) {
return X509_is_extension_set(this.x509Ptr, oid);
}
}
@@ -608,21 +1379,22 @@ public class WolfSSLCertificate {
* second list element being a String.
*
* @return immutable Collection of subject alternative names, or null
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
*/
- public Collection> getSubjectAltNames() {
+ public Collection> getSubjectAltNames()
+ throws IllegalStateException {
- synchronized (stateLock) {
- if (this.active == false) {
- throw new IllegalStateException("Object has been freed");
- }
+ confirmObjectIsActive();
- if (this.altNames != null) {
- /* already gathered, return cached version */
- return this.altNames;
- }
+ if (this.altNames != null) {
+ /* already gathered, return cached version */
+ return this.altNames;
+ }
- Collection> names = new ArrayList>();
+ Collection> names = new ArrayList>();
+ synchronized (x509Lock) {
String nextAltName = X509_get_next_altname(this.x509Ptr);
while (nextAltName != null) {
Object[] entry = new Object[2];
@@ -633,44 +1405,43 @@ public class WolfSSLCertificate {
names.add(Collections.unmodifiableList(entryList));
nextAltName = X509_get_next_altname(this.x509Ptr);
}
-
- /* cache altNames collection for later use */
- this.altNames = Collections.unmodifiableCollection(names);
-
- return this.altNames;
}
+
+ /* cache altNames collection for later use */
+ this.altNames = Collections.unmodifiableCollection(names);
+
+ return this.altNames;
}
/**
* Returns X509Certificate object based on this certificate.
*
* @return X509Certificate object
+ *
+ * @throws IllegalStateException if WolfSSLCertificate has been freed.
* @throws CertificateException on error
* @throws IOException on error closing ByteArrayInputStream
+ * @throws WolfSSLJNIException if native JNI error occurs
*/
public X509Certificate getX509Certificate()
- throws CertificateException, IOException {
+ throws IllegalStateException, CertificateException, IOException,
+ WolfSSLJNIException {
X509Certificate cert = null;
InputStream in = null;
-
CertificateFactory cf = CertificateFactory.getInstance("X.509");
- synchronized (stateLock) {
- if (this.active == false) {
- throw new CertificateException("Object has been freed");
- }
+ confirmObjectIsActive();
- try {
- in = new ByteArrayInputStream(this.getDer());
- cert = (X509Certificate)cf.generateCertificate(in);
+ try {
+ in = new ByteArrayInputStream(this.getDer());
+ cert = (X509Certificate)cf.generateCertificate(in);
+ in.close();
+
+ } catch (Exception e) {
+ if (in != null) {
in.close();
-
- } catch (Exception e) {
- if (in != null) {
- in.close();
- throw e;
- }
+ throw e;
}
}
@@ -687,7 +1458,9 @@ public class WolfSSLCertificate {
return super.toString();
}
- x509Text = X509_print(this.x509Ptr);
+ synchronized (x509Lock) {
+ x509Text = X509_print(this.x509Ptr);
+ }
if (x509Text != null) {
/* let Java do the modified UTF-8 conversion */
return new String(x509Text, Charset.forName("UTF-8"));
@@ -698,11 +1471,9 @@ public class WolfSSLCertificate {
}
/**
- * Frees an X509.
- *
- * @throws IllegalStateException WolfSSLCertificate has been freed
+ * Frees WolfSSLCertificate native resources.
*/
- public synchronized void free() throws IllegalStateException {
+ public synchronized void free() {
synchronized (stateLock) {
if (this.active == false) {
@@ -713,15 +1484,17 @@ public class WolfSSLCertificate {
/* set this.altNames to null so GC can free */
this.altNames = null;
- /* only free native resources if we own pointer */
- if (this.weOwnX509Ptr == true) {
- /* free native resources */
- X509_free(this.x509Ptr);
- }
+ synchronized (x509Lock) {
+ /* only free native resources if we own pointer */
+ if (this.weOwnX509Ptr == true) {
+ /* free native resources */
+ X509_free(this.x509Ptr);
+ }
- /* free Java resources */
- this.active = false;
- this.x509Ptr = 0;
+ /* free Java resources */
+ this.active = false;
+ this.x509Ptr = 0;
+ }
}
}
@@ -733,3 +1506,4 @@ public class WolfSSLCertificate {
super.finalize();
}
}
+
diff --git a/src/java/com/wolfssl/WolfSSLX509Name.java b/src/java/com/wolfssl/WolfSSLX509Name.java
new file mode 100644
index 0000000..316add3
--- /dev/null
+++ b/src/java/com/wolfssl/WolfSSLX509Name.java
@@ -0,0 +1,527 @@
+/* WolfSSLX509Name.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;
+
+/**
+ * WolfSSLX509Name class, wraps native WOLFSSL_X509_NAME functionality.
+ */
+public class WolfSSLX509Name {
+
+ private boolean active = false;
+ private long x509NamePtr = 0;
+
+ /* Lock around active state */
+ private final Object stateLock = new Object();
+
+ /* Cache name elements in Java before pushing through JNI, for easier
+ * retrieval from getXXX() methods */
+ private String countryName = null;
+ private String stateOrProvinceName = null;
+ private String streetAddress = null;
+ private String localityName = null;
+ private String surname = null;
+ private String commonName = null;
+ private String emailAddress = null;
+ private String organizationName = null;
+ private String organizationalUnitName = null;
+ private String postalCode = null;
+ private String userId = null;
+
+ /* Encoding types, matched to native define values */
+ private static final int MBSTRING_UTF8 = 0x100;
+
+ /* Native JNI methods */
+ static native long X509_NAME_new();
+ static native void X509_NAME_free(long x509Name);
+ static native int X509_NAME_add_entry_by_txt(long x509Name, String field,
+ int type, byte[] entry, int len, int loc, int set);
+
+ /**
+ * Create new empty WolfSSLX509Name object.
+ *
+ * @throws WolfSSLException if native API call fails.
+ */
+ public WolfSSLX509Name() throws WolfSSLException {
+
+ x509NamePtr = X509_NAME_new();
+ if (x509NamePtr == 0) {
+ throw new WolfSSLException("Failed to create WolfSSLX509Name");
+ }
+
+ synchronized (stateLock) {
+ this.active = true;
+ }
+ }
+
+ /**
+ * Verifies that the current WolfSSLX509Name object is active.
+ *
+ * @throws IllegalStateException if object has been freed
+ */
+ private void confirmObjectIsActive()
+ throws IllegalStateException {
+
+ synchronized (stateLock) {
+ if (this.active == false) {
+ throw new IllegalStateException(
+ "WolfSSLX509Name object has been freed");
+ }
+ }
+ }
+
+ /**
+ * For package use only, return native WOLFSSL_X509_NAME pointer.
+ *
+ * @return native WOLFSSL_X509_POINTER value
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ */
+ protected long getNativeX509NamePtr() throws IllegalStateException {
+
+ confirmObjectIsActive();
+
+ /* TODO lock around x509NamePtr */
+ return this.x509NamePtr;
+ }
+
+ /**
+ * Private helper function to call native JNI function
+ * X509_NAME_add_entry_by_txt().
+ *
+ * @param field String containing field name to set, for example
+ * "countryName"
+ * @param entry String value to store into field
+ *
+ * @throws WolfSSLException if arguments are invalid or error occurs
+ * with native JNI call.
+ */
+ private synchronized void addEntryByTxt(String field, String entry)
+ throws WolfSSLException {
+
+ int ret = 0;
+
+ if (field == null || entry == null) {
+ throw new WolfSSLException("field or entry is null in " +
+ "addEntryByTxt()");
+ }
+
+ ret = X509_NAME_add_entry_by_txt(this.x509NamePtr, field,
+ MBSTRING_UTF8, entry.getBytes(),
+ entry.getBytes().length, -1, 0);
+
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException("Error setting " + field + " into " +
+ "WolfSSLX509Name (error: " + ret + ")");
+ }
+ }
+
+ /**
+ * Set country name for this name object.
+ *
+ * @param countryName String containing country name to be set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ * @throws WolfSSLException if native JNI error has occurred, or input
+ * argument is invalid.
+ */
+ public synchronized void setCountryName(String countryName)
+ throws IllegalStateException, WolfSSLException {
+
+ confirmObjectIsActive();
+
+ addEntryByTxt("countryName", countryName);
+ this.countryName = countryName;
+ }
+
+ /**
+ * Set state or province name for this name object.
+ *
+ * @param name String containing state or province name to be set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ * @throws WolfSSLException if native JNI error has occurred, or input
+ * argument is invalid.
+ */
+ public synchronized void setStateOrProvinceName(String name)
+ throws IllegalStateException, WolfSSLException {
+
+ confirmObjectIsActive();
+
+ addEntryByTxt("stateOrProvinceName", name);
+ this.stateOrProvinceName = name;
+ }
+
+ /**
+ * Set street address for this name object.
+ *
+ * @param address String containing street address to be set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ * @throws WolfSSLException if native JNI error has occurred, or input
+ * argument is invalid.
+ */
+ public synchronized void setStreetAddress(String address)
+ throws IllegalStateException, WolfSSLException {
+
+ confirmObjectIsActive();
+
+ addEntryByTxt("streetAddress", address);
+ this.streetAddress = address;
+ }
+
+ /**
+ * Set locality name / city for this name object.
+ *
+ * @param name String containing locality name to be set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ * @throws WolfSSLException if native JNI error has occurred, or input
+ * argument is invalid.
+ */
+ public synchronized void setLocalityName(String name)
+ throws IllegalStateException, WolfSSLException {
+
+ confirmObjectIsActive();
+
+ addEntryByTxt("localityName", name);
+ this.localityName = name;
+ }
+
+ /**
+ * Set surname for this name object.
+ *
+ * @param name String containing surname to be set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ * @throws WolfSSLException if native JNI error has occurred, or input
+ * argument is invalid.
+ */
+ public synchronized void setSurname(String name)
+ throws IllegalStateException, WolfSSLException {
+
+ confirmObjectIsActive();
+
+ addEntryByTxt("surname", name);
+ this.surname = name;
+ }
+
+ /**
+ * Set common name for this name object.
+ *
+ * @param name String containing common name to be set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ * @throws WolfSSLException if native JNI error has occurred, or input
+ * argument is invalid.
+ */
+ public synchronized void setCommonName(String name)
+ throws IllegalStateException, WolfSSLException {
+
+ confirmObjectIsActive();
+
+ addEntryByTxt("commonName", name);
+ this.commonName = name;
+ }
+
+ /**
+ * Set email address for this name object.
+ *
+ * @param email String containing email address to be set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ * @throws WolfSSLException if native JNI error has occurred, or input
+ * argument is invalid.
+ */
+ public synchronized void setEmailAddress(String email)
+ throws IllegalStateException, WolfSSLException {
+
+ confirmObjectIsActive();
+
+ addEntryByTxt("emailAddress", email);
+ this.emailAddress = email;
+ }
+
+ /**
+ * Set organization name for this name object.
+ *
+ * @param name String containing organization name to be set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ * @throws WolfSSLException if native JNI error has occurred, or input
+ * argument is invalid.
+ */
+ public synchronized void setOrganizationName(String name)
+ throws IllegalStateException, WolfSSLException {
+
+ confirmObjectIsActive();
+
+ addEntryByTxt("organizationName", name);
+ this.organizationName = name;
+ }
+
+ /**
+ * Set organizational unit name for this name object.
+ *
+ * @param name String containing organizational unit name to be set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ * @throws WolfSSLException if native JNI error has occurred, or input
+ * argument is invalid.
+ */
+ public synchronized void setOrganizationalUnitName(String name)
+ throws IllegalStateException, WolfSSLException {
+
+ confirmObjectIsActive();
+
+ addEntryByTxt("organizationalUnitName", name);
+ this.organizationalUnitName = name;
+ }
+
+ /**
+ * Set postal code for this name object.
+ *
+ * @param code String containing postal code to be set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ * @throws WolfSSLException if native JNI error has occurred, or input
+ * argument is invalid.
+ */
+ public synchronized void setPostalCode(String code)
+ throws IllegalStateException, WolfSSLException {
+
+ confirmObjectIsActive();
+
+ addEntryByTxt("postalCode", code);
+ this.postalCode = code;
+ }
+
+ /**
+ * Set user ID for this name object.
+ *
+ * @param id String containing user ID to be set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ * @throws WolfSSLException if native JNI error has occurred, or input
+ * argument is invalid.
+ */
+ public synchronized void setUserId(String id)
+ throws IllegalStateException, WolfSSLException {
+
+ confirmObjectIsActive();
+
+ addEntryByTxt("userId", id);
+ this.userId = id;
+ }
+
+ /**
+ * Get country name set in this object.
+ *
+ * @return country name string, or null if not yet set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ */
+ public synchronized String getCountryName() {
+
+ confirmObjectIsActive();
+
+ return this.countryName;
+ }
+
+ /**
+ * Get state or province name set in this object.
+ *
+ * @return state or province name string, or null if not yet set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ */
+ public synchronized String getStateOrProvinceName() {
+
+ confirmObjectIsActive();
+
+ return this.stateOrProvinceName;
+ }
+
+ /**
+ * Get street address set in this object.
+ *
+ * @return street address string, or null if not yet set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ */
+ public synchronized String getStreetAddress() {
+
+ confirmObjectIsActive();
+
+ return this.streetAddress;
+ }
+
+ /**
+ * Get locality name set in this object.
+ *
+ * @return locality name string, or null if not yet set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ */
+ public synchronized String getLocalityName() {
+
+ confirmObjectIsActive();
+
+ return this.localityName;
+ }
+
+ /**
+ * Get surname set in this object.
+ *
+ * @return surname string, or null if not yet set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ */
+ public synchronized String getSurname() {
+
+ confirmObjectIsActive();
+
+ return this.surname;
+ }
+
+ /**
+ * Get common name set in this object.
+ *
+ * @return common name string, or null if not yet set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ */
+ public synchronized String getCommonName() {
+
+ confirmObjectIsActive();
+
+ return this.commonName;
+ }
+
+ /**
+ * Get email address set in this object.
+ *
+ * @return email address string, or null if not yet set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ */
+ public synchronized String getEmailAddress() {
+
+ confirmObjectIsActive();
+
+ return this.emailAddress;
+ }
+
+ /**
+ * Get organization name set in this object.
+ *
+ * @return organization name string, or null if not yet set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ */
+ public synchronized String getOrganizationName() {
+
+ confirmObjectIsActive();
+
+ return this.organizationName;
+ }
+
+ /**
+ * Get organizational unit name set in this object.
+ *
+ * @return organizational unit name string, or null if not yet set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ */
+ public synchronized String getOrganizationalUnitName() {
+
+ confirmObjectIsActive();
+
+ return this.organizationalUnitName;
+ }
+
+ /**
+ * Get postal code set in this object.
+ *
+ * @return postal code string, or null if not yet set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ */
+ public synchronized String getPostalCode() {
+
+ confirmObjectIsActive();
+
+ return this.postalCode;
+ }
+
+ /**
+ * Get user ID set in this object.
+ *
+ * @return user ID string, or null if not yet set
+ *
+ * @throws IllegalStateException if WolfSSLX509Name has been freed.
+ */
+ public synchronized String getUserId() {
+
+ confirmObjectIsActive();
+
+ return this.userId;
+ }
+
+ @Override
+ public String toString() {
+
+ synchronized (stateLock) {
+ if (this.active == false) {
+ return "";
+ }
+ }
+
+ /* TODO: wrap wolfSSL_X509_NAME_oneline() */
+ return null;
+ }
+
+ /**
+ * Free native resources of WolfSSLX509Name.
+ */
+ public synchronized void free() {
+
+ synchronized (stateLock) {
+ if (this.active == false) {
+ /* already freed, just return */
+ return;
+ }
+
+ /* free native resources */
+ X509_NAME_free(this.x509NamePtr);
+
+ this.active = false;
+ this.x509NamePtr = 0;
+ }
+ }
+
+ @SuppressWarnings("deprecation")
+ @Override
+ protected void finalize() throws Throwable
+ {
+ this.free();
+ super.finalize();
+ }
+}
+
diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java b/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java
index d24fb93..9b69883 100644
--- a/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java
+++ b/src/java/com/wolfssl/provider/jsse/WolfSSLInternalVerifyCb.java
@@ -22,6 +22,7 @@ package com.wolfssl.provider.jsse;
import com.wolfssl.WolfSSLVerifyCallback;
import com.wolfssl.WolfSSLException;
+import com.wolfssl.WolfSSLJNIException;
import com.wolfssl.WolfSSLCertificate;
import com.wolfssl.WolfSSLX509StoreCtx;
import com.wolfssl.provider.jsse.WolfSSLInternalVerifyCb;
@@ -103,7 +104,8 @@ public class WolfSSLInternalVerifyCb implements WolfSSLVerifyCallback {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"Peer cert: " + x509certs[i].getSubjectDN().getName());
}
- } catch (CertificateException | IOException ce) {
+ } catch (CertificateException | IOException |
+ WolfSSLJNIException ce) {
/* failed to get cert array, give app null array */
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"Failed to get X509Certificate[] array, set to null");
diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLTrustManager.java b/src/java/com/wolfssl/provider/jsse/WolfSSLTrustManager.java
index 8bbe3db..535819b 100644
--- a/src/java/com/wolfssl/provider/jsse/WolfSSLTrustManager.java
+++ b/src/java/com/wolfssl/provider/jsse/WolfSSLTrustManager.java
@@ -40,6 +40,7 @@ import javax.net.ssl.TrustManagerFactorySpi;
import com.wolfssl.WolfSSL;
import com.wolfssl.WolfSSLCertificate;
import com.wolfssl.WolfSSLException;
+import com.wolfssl.WolfSSLJNIException;
/**
* wolfSSL implemenation of TrustManagerFactorySpi
@@ -346,6 +347,8 @@ public class WolfSSLTrustManager extends TrustManagerFactorySpi {
throw new KeyStoreException(ex);
} catch (CertificateException ex) {
throw new KeyStoreException(ex);
+ } catch (WolfSSLJNIException ex) {
+ throw new KeyStoreException(ex);
}
}
this.store = certs;
diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLX509.java b/src/java/com/wolfssl/provider/jsse/WolfSSLX509.java
index 8f5fb34..dd021b0 100644
--- a/src/java/com/wolfssl/provider/jsse/WolfSSLX509.java
+++ b/src/java/com/wolfssl/provider/jsse/WolfSSLX509.java
@@ -45,6 +45,7 @@ import java.util.Collection;
import com.wolfssl.WolfSSLCertificate;
import com.wolfssl.WolfSSLException;
+import com.wolfssl.WolfSSLJNIException;
/**
* wolfSSL implementation of X509Certificate
@@ -334,11 +335,17 @@ public class WolfSSLX509 extends X509Certificate {
if (this.cert == null) {
return null;
}
- byte[] ret = this.cert.getDer();
- if (ret == null) {
- throw new CertificateEncodingException();
+
+ try {
+ byte[] ret = this.cert.getDer();
+ if (ret == null) {
+ throw new CertificateEncodingException();
+ }
+ return ret;
+
+ } catch (WolfSSLJNIException e) {
+ throw new CertificateEncodingException(e);
}
- return ret;
}
@Override
diff --git a/src/test/com/wolfssl/test/WolfSSLCertificateTest.java b/src/test/com/wolfssl/test/WolfSSLCertificateTest.java
index ff7d837..b6c401b 100644
--- a/src/test/com/wolfssl/test/WolfSSLCertificateTest.java
+++ b/src/test/com/wolfssl/test/WolfSSLCertificateTest.java
@@ -27,15 +27,37 @@ import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
-import static org.junit.Assert.fail;
+import java.time.Instant;
+import java.time.Duration;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.KeyPairGenerator;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.PublicKey;
+import java.security.PrivateKey;
+import java.security.NoSuchAlgorithmException;
+
import org.junit.Test;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import static org.junit.Assert.*;
import com.wolfssl.WolfSSL;
+import com.wolfssl.WolfSSLX509Name;
import com.wolfssl.WolfSSLCertificate;
+import com.wolfssl.WolfSSLCertManager;
import com.wolfssl.WolfSSLException;
+import com.wolfssl.WolfSSLJNIException;
/**
*
@@ -47,19 +69,39 @@ public class WolfSSLCertificateTest {
public static String cliCertDer = "examples/certs/client-cert.der";
public static String cliCertPem = "examples/certs/client-cert.pem";
+ public static String cliKeyDer = "examples/certs/client-key.der";
+ public static String cliKeyPubDer = "examples/certs/client-keyPub.der";
+ public static String caCertPem = "examples/certs/ca-cert.pem";
+ public static String caKeyDer = "examples/certs/ca-key.der";
+ public static String caKeyPkcs8Der = "examples/certs/ca-keyPkcs8.der";
+ public static String serverCertPem = "examples/certs/server-cert.pem";
public static String external = "examples/certs/ca-google-root.der";
public static String bogusFile = "/dev/null";
private WolfSSLCertificate cert;
+ @BeforeClass
+ public static void setCertPaths() throws WolfSSLException {
+
+ try {
+ WolfSSL.loadLibrary();
+ } catch (UnsatisfiedLinkError ule) {
+ fail("failed to load native JNI library");
+ }
+
+ cliCertDer = WolfSSLTestCommon.getPath(cliCertDer);
+ cliCertPem = WolfSSLTestCommon.getPath(cliCertPem);
+ cliKeyPubDer = WolfSSLTestCommon.getPath(cliKeyPubDer);
+ caCertPem = WolfSSLTestCommon.getPath(caCertPem);
+ caKeyDer = WolfSSLTestCommon.getPath(caKeyDer);
+ external = WolfSSLTestCommon.getPath(external);
+ }
+
+
@Test
public void testWolfSSLCertificate() throws WolfSSLException {
System.out.println("WolfSSLCertificate Class");
- cliCertDer = WolfSSLTestCommon.getPath(cliCertDer);
- cliCertPem = WolfSSLTestCommon.getPath(cliCertPem);
- external = WolfSSLTestCommon.getPath(external);
-
/* WolfSSLCertificate(byte[] der) */
test_WolfSSLCertificate_new_derArray();
test_runCertTestsAfterConstructor();
@@ -79,7 +121,6 @@ public class WolfSSLCertificateTest {
}
}
-
public void test_runCertTestsAfterConstructor() {
test_getSerial();
test_notBefore();
@@ -95,7 +136,11 @@ public class WolfSSLCertificateTest {
test_getSignatureType();
test_verify();
test_getSignatureOID();
- test_getKeyUsage();
+ if (WolfSSL.getLibVersionHex() > 0x05006003) {
+ /* Key Usage and Extended Key Usage only work with wolfSSL
+ * later than 5.6.3 */
+ test_getKeyUsage();
+ }
test_getExtensionSet();
test_toString();
test_free();
@@ -208,11 +253,11 @@ public class WolfSSLCertificateTest {
public void test_getSerial() {
- byte[] expected = new byte[]{
- (byte)0x01, (byte)0x1a, (byte)0xeb, (byte)0x56, (byte)0xab,
- (byte)0xdc, (byte)0x8b, (byte)0xf3, (byte)0xa6, (byte)0x1e,
- (byte)0xf4, (byte)0x93, (byte)0x60, (byte)0x89, (byte)0xb7,
- (byte)0x05, (byte)0x07, (byte)0x29, (byte)0x01, (byte)0x2c
+ byte[] expected = new byte[] {
+ (byte)0x73, (byte)0xfb, (byte)0x54, (byte)0xd6, (byte)0x03,
+ (byte)0x7d, (byte)0x4c, (byte)0x07, (byte)0x84, (byte)0xe2,
+ (byte)0x00, (byte)0x11, (byte)0x8c, (byte)0xdd, (byte)0x90,
+ (byte)0xdc, (byte)0x48, (byte)0x8d, (byte)0xea, (byte)0x53
};
byte[] serial;
int i;
@@ -232,7 +277,7 @@ public class WolfSSLCertificateTest {
@SuppressWarnings("deprecation")
public void test_notBefore() {
Date date = cert.notBefore();
- Date expected = new Date("Feb 15 12:50:24 2022 GMT");
+ Date expected = new Date("Dec 16 21:17:49 2022 GMT");
System.out.print("\t\tnotBefore");
if (date.compareTo(expected) != 0) {
System.out.println("\t\t... failed");
@@ -245,7 +290,7 @@ public class WolfSSLCertificateTest {
@SuppressWarnings("deprecation")
public void test_notAfter() {
Date date = cert.notAfter();
- Date expected = new Date("Nov 11 12:50:24 2024 GMT");
+ Date expected = new Date("Sep 11 21:17:49 2025 GMT");
System.out.print("\t\tnotAfter");
if (date.compareTo(expected) != 0) {
System.out.println("\t\t... failed");
@@ -268,49 +313,58 @@ public class WolfSSLCertificateTest {
public void test_getSignature() {
byte[] sig = cert.getSignature();
byte[] expected = new byte[] {
- (byte)0x64, (byte)0x6d, (byte)0xa6, (byte)0x4a, (byte)0xa8, (byte)0x9f,
- (byte)0xa7, (byte)0xe9, (byte)0x75, (byte)0x2c, (byte)0xf3, (byte)0x85,
- (byte)0x3d, (byte)0x3e, (byte)0xaf, (byte)0x38, (byte)0xfb, (byte)0x6c,
- (byte)0xc7, (byte)0xeb, (byte)0xc7, (byte)0xd0, (byte)0x2b, (byte)0xa2,
- (byte)0x45, (byte)0xb5, (byte)0x65, (byte)0xbe, (byte)0xd0, (byte)0x13,
- (byte)0x2c, (byte)0xf7, (byte)0xa3, (byte)0xc1, (byte)0xeb, (byte)0x3c,
- (byte)0xb1, (byte)0xf8, (byte)0xb8, (byte)0x3d, (byte)0x63, (byte)0x8f,
- (byte)0xca, (byte)0x08, (byte)0x4e, (byte)0x65, (byte)0x1d, (byte)0x2c,
- (byte)0xce, (byte)0x34, (byte)0x6e, (byte)0x35, (byte)0x96, (byte)0x87,
- (byte)0x93, (byte)0x30, (byte)0x5d, (byte)0xaa, (byte)0xc8, (byte)0xe9,
- (byte)0xa0, (byte)0x9c, (byte)0x9b, (byte)0x84, (byte)0x78, (byte)0x3a,
- (byte)0x52, (byte)0xa1, (byte)0x33, (byte)0x48, (byte)0x6e, (byte)0x84,
- (byte)0x66, (byte)0x71, (byte)0x9c, (byte)0xcf, (byte)0xd1, (byte)0xc7,
- (byte)0x7b, (byte)0x02, (byte)0x4c, (byte)0xe1, (byte)0x49, (byte)0x7c,
- (byte)0x69, (byte)0x47, (byte)0xfc, (byte)0xb7, (byte)0x01, (byte)0xf9,
- (byte)0xa0, (byte)0x39, (byte)0x3b, (byte)0xab, (byte)0xb9, (byte)0xc6,
- (byte)0xd9, (byte)0xca, (byte)0x27, (byte)0x85, (byte)0xf0, (byte)0x5c,
- (byte)0xb6, (byte)0xa4, (byte)0xe6, (byte)0xdc, (byte)0xf2, (byte)0x52,
- (byte)0xfe, (byte)0x44, (byte)0x00, (byte)0xb6, (byte)0xf0, (byte)0x47,
- (byte)0xf2, (byte)0x6f, (byte)0x3f, (byte)0xd5, (byte)0x0f, (byte)0xff,
- (byte)0x31, (byte)0x93, (byte)0x53, (byte)0x88, (byte)0x8c, (byte)0xc7,
- (byte)0xfb, (byte)0x56, (byte)0x10, (byte)0x4b, (byte)0x3b, (byte)0x43,
- (byte)0xe6, (byte)0x8a, (byte)0x9c, (byte)0xb7, (byte)0xb4, (byte)0x9a,
- (byte)0xdd, (byte)0x5c, (byte)0xe3, (byte)0xcd, (byte)0x9c, (byte)0xbd,
- (byte)0xa7, (byte)0x0c, (byte)0xc1, (byte)0xd9, (byte)0x96, (byte)0xf0,
- (byte)0x93, (byte)0xf3, (byte)0xab, (byte)0xbd, (byte)0xd2, (byte)0x1e,
- (byte)0x77, (byte)0x8a, (byte)0x42, (byte)0xcd, (byte)0x0f, (byte)0xfe,
- (byte)0x48, (byte)0xda, (byte)0x57, (byte)0x34, (byte)0x61, (byte)0x46,
- (byte)0xa3, (byte)0x89, (byte)0x2e, (byte)0x31, (byte)0xd2, (byte)0x4a,
- (byte)0xd4, (byte)0x43, (byte)0x2f, (byte)0x56, (byte)0x85, (byte)0x44,
- (byte)0x75, (byte)0xca, (byte)0x6b, (byte)0x36, (byte)0xe2, (byte)0xe8,
- (byte)0x3a, (byte)0xb2, (byte)0x95, (byte)0x95, (byte)0x3a, (byte)0x28,
- (byte)0x90, (byte)0x8d, (byte)0xc0, (byte)0x23, (byte)0xfb, (byte)0x3c,
- (byte)0xd2, (byte)0x1a, (byte)0x73, (byte)0x6b, (byte)0xef, (byte)0xfd,
- (byte)0xd6, (byte)0x1b, (byte)0xeb, (byte)0x6d, (byte)0x67, (byte)0x2a,
- (byte)0xe1, (byte)0xeb, (byte)0x2a, (byte)0x83, (byte)0x22, (byte)0xad,
- (byte)0xe3, (byte)0x95, (byte)0x19, (byte)0xe5, (byte)0x93, (byte)0xee,
- (byte)0x14, (byte)0xdc, (byte)0xb5, (byte)0x7d, (byte)0xe7, (byte)0xcf,
- (byte)0x89, (byte)0x8c, (byte)0xd7, (byte)0x8f, (byte)0xd2, (byte)0x3f,
- (byte)0x68, (byte)0x7e, (byte)0xa9, (byte)0x74, (byte)0x7c, (byte)0x1b,
- (byte)0x38, (byte)0x65, (byte)0xf9, (byte)0x28, (byte)0x4d, (byte)0xff,
- (byte)0x50, (byte)0xc8, (byte)0xee, (byte)0x51, (byte)0x3a, (byte)0x8f,
- (byte)0x1d, (byte)0x9e, (byte)0x55, (byte)0x5e
+ (byte)0x36, (byte)0xcb, (byte)0xbc, (byte)0xc5, (byte)0x52,
+ (byte)0x9a, (byte)0x66, (byte)0xcd, (byte)0x91, (byte)0x4d,
+ (byte)0x8f, (byte)0x27, (byte)0x9f, (byte)0xb3, (byte)0x64,
+ (byte)0x80, (byte)0x0e, (byte)0x64, (byte)0xb4, (byte)0xcb,
+ (byte)0x1a, (byte)0xcd, (byte)0x75, (byte)0x9e, (byte)0x82,
+ (byte)0x7c, (byte)0x55, (byte)0x67, (byte)0xd8, (byte)0x9f,
+ (byte)0x90, (byte)0xa3, (byte)0x34, (byte)0x96, (byte)0x99,
+ (byte)0x43, (byte)0xf7, (byte)0x49, (byte)0x53, (byte)0xa2,
+ (byte)0x58, (byte)0x85, (byte)0xa0, (byte)0xb3, (byte)0x83,
+ (byte)0x4f, (byte)0xaf, (byte)0xb8, (byte)0x15, (byte)0x8a,
+ (byte)0x88, (byte)0x1e, (byte)0xf3, (byte)0x60, (byte)0xf4,
+ (byte)0x7c, (byte)0x94, (byte)0xb5, (byte)0x58, (byte)0x68,
+ (byte)0xf1, (byte)0x2a, (byte)0x13, (byte)0x80, (byte)0x34,
+ (byte)0xc2, (byte)0x6f, (byte)0xa5, (byte)0xf8, (byte)0x7e,
+ (byte)0x76, (byte)0x16, (byte)0x81, (byte)0x4f, (byte)0x36,
+ (byte)0x8b, (byte)0xc3, (byte)0x59, (byte)0xbd, (byte)0x51,
+ (byte)0xdd, (byte)0x60, (byte)0x87, (byte)0xd7, (byte)0x1d,
+ (byte)0x96, (byte)0x44, (byte)0x69, (byte)0x07, (byte)0x3c,
+ (byte)0x8f, (byte)0x28, (byte)0x56, (byte)0xb1, (byte)0x11,
+ (byte)0x5c, (byte)0x4e, (byte)0x81, (byte)0x3f, (byte)0x57,
+ (byte)0x25, (byte)0xfd, (byte)0x65, (byte)0xdd, (byte)0x07,
+ (byte)0xcf, (byte)0x17, (byte)0x0a, (byte)0x01, (byte)0x7e,
+ (byte)0x4e, (byte)0x3f, (byte)0x8e, (byte)0x73, (byte)0xdb,
+ (byte)0xfe, (byte)0xf4, (byte)0xf2, (byte)0xc5, (byte)0xff,
+ (byte)0xa3, (byte)0x76, (byte)0xa8, (byte)0x74, (byte)0x46,
+ (byte)0x2e, (byte)0x47, (byte)0x0d, (byte)0xb0, (byte)0xed,
+ (byte)0x0a, (byte)0xc0, (byte)0xc5, (byte)0x0a, (byte)0x65,
+ (byte)0xd3, (byte)0xdc, (byte)0x62, (byte)0xb2, (byte)0xe0,
+ (byte)0x1e, (byte)0x8e, (byte)0xbd, (byte)0xf3, (byte)0xbd,
+ (byte)0xaf, (byte)0xaf, (byte)0x66, (byte)0x84, (byte)0x36,
+ (byte)0x92, (byte)0xe2, (byte)0x3b, (byte)0x80, (byte)0xd0,
+ (byte)0x57, (byte)0xa6, (byte)0x41, (byte)0xa3, (byte)0x62,
+ (byte)0xd1, (byte)0xa6, (byte)0x6d, (byte)0x14, (byte)0x6c,
+ (byte)0xcd, (byte)0x82, (byte)0xb1, (byte)0xc1, (byte)0xc1,
+ (byte)0x35, (byte)0x55, (byte)0xae, (byte)0x59, (byte)0x49,
+ (byte)0xa8, (byte)0x26, (byte)0x52, (byte)0xbd, (byte)0xef,
+ (byte)0x1b, (byte)0x2c, (byte)0x1f, (byte)0x9d, (byte)0x39,
+ (byte)0x04, (byte)0xd2, (byte)0x82, (byte)0xa0, (byte)0x6b,
+ (byte)0x39, (byte)0x71, (byte)0x59, (byte)0x33, (byte)0x82,
+ (byte)0xba, (byte)0x55, (byte)0x6c, (byte)0x97, (byte)0xf2,
+ (byte)0x1b, (byte)0x5b, (byte)0xe0, (byte)0x4d, (byte)0xe2,
+ (byte)0xcf, (byte)0x89, (byte)0xe7, (byte)0x26, (byte)0xb8,
+ (byte)0x2c, (byte)0x6c, (byte)0x9f, (byte)0x83, (byte)0xd6,
+ (byte)0xed, (byte)0x4e, (byte)0x2f, (byte)0x75, (byte)0xa9,
+ (byte)0x30, (byte)0x4e, (byte)0x01, (byte)0x95, (byte)0x0d,
+ (byte)0x4f, (byte)0x83, (byte)0x5e, (byte)0xc8, (byte)0xaf,
+ (byte)0x7f, (byte)0x67, (byte)0xea, (byte)0x53, (byte)0xbf,
+ (byte)0xca, (byte)0x9b, (byte)0x1f, (byte)0xd4, (byte)0xff,
+ (byte)0x36, (byte)0x97, (byte)0x02, (byte)0x71, (byte)0x8e,
+ (byte)0x33, (byte)0xde, (byte)0xe2, (byte)0x58, (byte)0x27,
+ (byte)0xaa, (byte)0x70, (byte)0x0c, (byte)0x5b, (byte)0xde,
+ (byte)0x0e
};
int i;
System.out.print("\t\tgetSignature");
@@ -577,4 +631,616 @@ public class WolfSSLCertificateTest {
this.cert.free();
System.out.println("\t\t\t... passed");
}
+
+ @Test
+ public void testWolfSSLCertificateGeneration()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException, NoSuchAlgorithmException,
+ InvalidKeySpecException {
+
+ System.out.println("WolfSSLCertificate Generation");
+
+ if (WolfSSL.FileSystemEnabled() == true) {
+ testCertGen_SelfSigned_UsingFiles();
+ testCertGen_SelfSigned_UsingBuffers();
+ testCertGen_SelfSigned_UsingJavaClasses();
+ testCertGen_CASigned_UsingFiles();
+ testCertGen_CASigned_UsingBuffers();
+ testCertGen_CASigned_UsingJavaClasses();
+ }
+ }
+
+ /* Quick sanity check on certificate bytes. Loads cert into new
+ * WolfSSLCertificate object, tries to get various elements and
+ * simply verify if not null / etc. */
+ private void sanityCheckCertFileBytes(byte[] certBytes, int type)
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException {
+
+ if (certBytes == null ||
+ (type != WolfSSL.SSL_FILETYPE_ASN1 &&
+ type != WolfSSL.SSL_FILETYPE_PEM)) {
+ throw new WolfSSLException("certBytes is null or bad type");
+ }
+
+ WolfSSLCertificate tmp = new WolfSSLCertificate(certBytes, type);
+ assertNotNull(tmp);
+ assertNotNull(tmp.getDer());
+ assertNotNull(tmp.getPem());
+ assertNotNull(tmp.getTbs());
+ assertNotNull(tmp.getSerial());
+ assertNotNull(tmp.notBefore());
+ assertNotNull(tmp.notAfter());
+ assertTrue(tmp.getVersion() >= 0);
+ assertNotNull(tmp.getSignature());
+ assertNotNull(tmp.getSignatureType());
+ assertNotNull(tmp.getSignatureOID());
+ assertNotNull(tmp.getPubkey());
+ assertNotNull(tmp.getPubkeyType());
+ int isCA = tmp.isCA();
+ assertTrue(isCA == 0 || isCA == 1);
+ assertTrue(tmp.getPathLen() >= -1);
+ assertNotNull(tmp.getSubject());
+ assertNotNull(tmp.getIssuer());
+ if (WolfSSL.getLibVersionHex() > 0x05006003) {
+ /* Key Usage and Extended Key Usage only work with wolfSSL
+ * later than 5.6.3 */
+ assertNotNull(tmp.getKeyUsage());
+ }
+ assertNotNull(tmp.getSubjectAltNames());
+ assertNotNull(tmp.getX509Certificate());
+ assertNotNull(tmp.toString());
+ }
+
+ /* Make sure peer cert can be verified using CertManager and provided
+ * CA cert (and optional intermediate CA cert if needed). Supports PEM and
+ * DER. Throws WolfSSLException if not valid. */
+ private void verifyCertSignatureIsCorrect(
+ byte[] peerCert, int peerCertType,
+ byte[] intCaCert, int intCaCertType,
+ byte[] rootCaCert, int rootCaCertType) throws WolfSSLException {
+
+ int ret = WolfSSL.SSL_FAILURE;
+ WolfSSLCertManager cm = new WolfSSLCertManager();
+
+ if (peerCert == null || rootCaCert == null ||
+ (peerCertType != WolfSSL.SSL_FILETYPE_ASN1 &&
+ peerCertType != WolfSSL.SSL_FILETYPE_PEM) ||
+ (rootCaCertType != WolfSSL.SSL_FILETYPE_ASN1 &&
+ rootCaCertType != WolfSSL.SSL_FILETYPE_PEM)) {
+ throw new WolfSSLException("cert or CA cert is null or bad type");
+ }
+
+ /* Load root CA as trusted */
+ ret = cm.CertManagerLoadCABuffer(rootCaCert, rootCaCert.length,
+ rootCaCertType);
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException("Failed to load CA for verifying");
+ }
+
+ /* Load intermediate CA as trusted if needed */
+ if (intCaCert != null) {
+ if (intCaCertType != WolfSSL.SSL_FILETYPE_ASN1 &&
+ intCaCertType != WolfSSL.SSL_FILETYPE_PEM) {
+ throw new WolfSSLException("intermediate cert is bad type");
+ }
+
+ ret = cm.CertManagerLoadCABuffer(intCaCert, intCaCert.length,
+ intCaCertType);
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException(
+ "Failed to load intermediate CA for verifying");
+ }
+ }
+
+ ret = cm.CertManagerVerifyBuffer(peerCert, peerCert.length,
+ peerCertType);
+ if (ret != WolfSSL.SSL_SUCCESS) {
+ throw new WolfSSLException("Failed to verify peer cert against CA");
+ }
+ }
+
+
+ /* 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 self-signed certificate generation using files for public key,
+ * issuer name, and issuer private key */
+ private void testCertGen_SelfSigned_UsingFiles()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException {
+
+ System.out.print("\tself signed (files)");
+
+ WolfSSLCertificate x509 = new WolfSSLCertificate();
+ assertNotNull(x509);
+
+ /* Set notBefore/notAfter dates */
+ Instant now = Instant.now();
+ final Date notBefore = Date.from(now);
+ final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
+ x509.setNotBefore(notBefore);
+ x509.setNotAfter(notAfter);
+
+ /* Set serial number */
+ x509.setSerialNumber(BigInteger.valueOf(12345));
+
+ /* Set Subject Name */
+ WolfSSLX509Name subjectName = GenerateTestSubjectName();
+ assertNotNull(subjectName);
+ x509.setSubjectName(subjectName);
+
+ /* Not setting Issuer, since generating self-signed cert */
+
+ /* Set Public Key from file */
+ x509.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 */
+ x509.addExtension(WolfSSL.NID_key_usage,
+ "digitalSignature,keyEncipherment,dataEncipherment", false);
+
+ x509.addExtension(WolfSSL.NID_ext_key_usage,
+ "clientAuth,serverAuth", false);
+ }
+ x509.addExtension(WolfSSL.NID_subject_alt_name,
+ "test.wolfssl.com", false);
+ x509.addExtension(WolfSSL.NID_basic_constraints, true, true);
+
+ /* Sign cert, self-signed */
+ x509.signCert(cliKeyDer, WolfSSL.RSAk,
+ WolfSSL.SSL_FILETYPE_ASN1, "SHA256");
+
+ /* Output to DER and PEM */
+ byte[] derCert = x509.getDer();
+ byte[] pemCert = x509.getPem();
+
+ assertNotNull(derCert);
+ assertTrue(derCert.length > 0);
+ assertNotNull(pemCert);
+ assertTrue(pemCert.length > 0);
+
+ /* Sanity check generated cert buffers */
+ sanityCheckCertFileBytes(derCert, WolfSSL.SSL_FILETYPE_ASN1);
+ sanityCheckCertFileBytes(pemCert, WolfSSL.SSL_FILETYPE_PEM);
+
+ /* Sanity check CertManager can verify signature using expected CA */
+ verifyCertSignatureIsCorrect(derCert, WolfSSL.SSL_FILETYPE_ASN1,
+ null, 0, derCert, WolfSSL.SSL_FILETYPE_ASN1);
+ verifyCertSignatureIsCorrect(pemCert, WolfSSL.SSL_FILETYPE_PEM,
+ null, 0, derCert, WolfSSL.SSL_FILETYPE_ASN1);
+
+ /* Free native memory */
+ subjectName.free();
+ x509.free();
+
+ System.out.println("\t\t... passed");
+ }
+
+ /* Test CA-signed certificate generation using files for public key,
+ * issuer name, and issuer private key */
+ private void testCertGen_CASigned_UsingFiles()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException {
+
+ System.out.print("\tCA signed (files)");
+
+ WolfSSLCertificate x509 = new WolfSSLCertificate();
+ assertNotNull(x509);
+
+ /* Set notBefore/notAfter dates */
+ Instant now = Instant.now();
+ final Date notBefore = Date.from(now);
+ final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
+ x509.setNotBefore(notBefore);
+ x509.setNotAfter(notAfter);
+
+ /* Set serial number */
+ x509.setSerialNumber(BigInteger.valueOf(12345));
+
+ /* Set Subject Name */
+ WolfSSLX509Name subjectName = GenerateTestSubjectName();
+ assertNotNull(subjectName);
+ x509.setSubjectName(subjectName);
+
+ /* Set Issuer Name from existing PEM file */
+ WolfSSLCertificate issuer =
+ new WolfSSLCertificate(caCertPem, WolfSSL.SSL_FILETYPE_PEM);
+ x509.setIssuerName(issuer);
+
+ /* Set Public Key from file */
+ x509.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 */
+ x509.addExtension(WolfSSL.NID_key_usage,
+ "digitalSignature,keyEncipherment,dataEncipherment", false);
+ x509.addExtension(WolfSSL.NID_ext_key_usage,
+ "clientAuth,serverAuth", false);
+ }
+ x509.addExtension(WolfSSL.NID_subject_alt_name,
+ "test.wolfssl.com", false);
+ x509.addExtension(WolfSSL.NID_basic_constraints, false, true);
+
+ /* Sign cert, CA-signed */
+ x509.signCert(caKeyDer, WolfSSL.RSAk,
+ WolfSSL.SSL_FILETYPE_ASN1, "SHA256");
+
+ /* Output to DER and PEM */
+ byte[] derCert = x509.getDer();
+ byte[] pemCert = x509.getPem();
+
+ assertNotNull(derCert);
+ assertTrue(derCert.length > 0);
+ assertNotNull(pemCert);
+ assertTrue(pemCert.length > 0);
+
+ /* Sanity check generated cert buffers */
+ sanityCheckCertFileBytes(derCert, WolfSSL.SSL_FILETYPE_ASN1);
+ sanityCheckCertFileBytes(pemCert, WolfSSL.SSL_FILETYPE_PEM);
+
+ /* Sanity check CertManager can verify signature using expected CA */
+ verifyCertSignatureIsCorrect(derCert, WolfSSL.SSL_FILETYPE_ASN1,
+ null, 0, issuer.getDer(), WolfSSL.SSL_FILETYPE_ASN1);
+ verifyCertSignatureIsCorrect(pemCert, WolfSSL.SSL_FILETYPE_PEM,
+ null, 0, issuer.getDer(), WolfSSL.SSL_FILETYPE_ASN1);
+
+ /* Free native memory */
+ subjectName.free();
+ x509.free();
+
+ System.out.println("\t\t... passed");
+ }
+
+ /* Test self-signed certificate generation using buffers for public key,
+ * issuer name, and issuer private key */
+ private void testCertGen_SelfSigned_UsingBuffers()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException {
+
+ System.out.print("\tself signed (buffers)");
+
+ WolfSSLCertificate x509 = new WolfSSLCertificate();
+ assertNotNull(x509);
+
+ /* Set notBefore/notAfter dates */
+ Instant now = Instant.now();
+ final Date notBefore = Date.from(now);
+ final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
+ x509.setNotBefore(notBefore);
+ x509.setNotAfter(notAfter);
+
+ /* Set serial number */
+ x509.setSerialNumber(BigInteger.valueOf(12345));
+
+ /* Set Subject Name */
+ WolfSSLX509Name subjectName = GenerateTestSubjectName();
+ assertNotNull(subjectName);
+ x509.setSubjectName(subjectName);
+
+ /* Not setting Issuer, since generating self-signed cert */
+
+ /* Set Public Key from file */
+ byte[] pubKey = Files.readAllBytes(Paths.get(cliKeyPubDer));
+ x509.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 */
+ x509.addExtension(WolfSSL.NID_key_usage,
+ "digitalSignature,keyEncipherment,dataEncipherment", false);
+ x509.addExtension(WolfSSL.NID_ext_key_usage,
+ "clientAuth,serverAuth", false);
+ }
+ x509.addExtension(WolfSSL.NID_subject_alt_name,
+ "test.wolfssl.com", false);
+ x509.addExtension(WolfSSL.NID_basic_constraints, true, true);
+
+ /* Sign cert, self-signed */
+ byte[] privKey = Files.readAllBytes(Paths.get(cliKeyDer));
+ x509.signCert(privKey, WolfSSL.RSAk,
+ WolfSSL.SSL_FILETYPE_ASN1, "SHA256");
+
+ /* Output to DER and PEM */
+ byte[] derCert = x509.getDer();
+ byte[] pemCert = x509.getPem();
+
+ assertNotNull(derCert);
+ assertTrue(derCert.length > 0);
+ assertNotNull(pemCert);
+ assertTrue(pemCert.length > 0);
+
+ /* Sanity check generated cert buffers */
+ sanityCheckCertFileBytes(derCert, WolfSSL.SSL_FILETYPE_ASN1);
+ sanityCheckCertFileBytes(pemCert, WolfSSL.SSL_FILETYPE_PEM);
+
+ /* Sanity check CertManager can verify signature using expected CA */
+ verifyCertSignatureIsCorrect(derCert, WolfSSL.SSL_FILETYPE_ASN1,
+ null, 0, derCert, WolfSSL.SSL_FILETYPE_ASN1);
+ verifyCertSignatureIsCorrect(pemCert, WolfSSL.SSL_FILETYPE_PEM,
+ null, 0, derCert, WolfSSL.SSL_FILETYPE_ASN1);
+
+ /* Free native memory */
+ subjectName.free();
+ x509.free();
+
+ System.out.println("\t\t... passed");
+ }
+
+ /* Test CA-signed certificate generation using buffers for public key,
+ * issuer name, and issuer private key */
+ private void testCertGen_CASigned_UsingBuffers()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException {
+
+ System.out.print("\tCA signed (buffers)");
+
+ WolfSSLCertificate x509 = new WolfSSLCertificate();
+ assertNotNull(x509);
+
+ /* Set notBefore/notAfter dates */
+ Instant now = Instant.now();
+ final Date notBefore = Date.from(now);
+ final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
+ x509.setNotBefore(notBefore);
+ x509.setNotAfter(notAfter);
+
+ /* Set serial number */
+ x509.setSerialNumber(BigInteger.valueOf(12345));
+
+ /* Set Subject Name */
+ WolfSSLX509Name subjectName = GenerateTestSubjectName();
+ assertNotNull(subjectName);
+ x509.setSubjectName(subjectName);
+
+ /* Set Issuer Name from existing PEM file */
+ WolfSSLCertificate issuer =
+ new WolfSSLCertificate(Files.readAllBytes(Paths.get(caCertPem)),
+ WolfSSL.SSL_FILETYPE_PEM);
+ x509.setIssuerName(issuer);
+
+ /* Set Public Key from file */
+ byte[] pubKey = Files.readAllBytes(Paths.get(cliKeyPubDer));
+ x509.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 */
+ x509.addExtension(WolfSSL.NID_key_usage,
+ "digitalSignature,keyEncipherment,dataEncipherment", false);
+ x509.addExtension(WolfSSL.NID_ext_key_usage,
+ "clientAuth,serverAuth", false);
+ }
+ x509.addExtension(WolfSSL.NID_subject_alt_name,
+ "test.wolfssl.com", false);
+ x509.addExtension(WolfSSL.NID_basic_constraints, false, true);
+
+ /* Sign cert, CA-signed */
+ byte[] privKey = Files.readAllBytes(Paths.get(caKeyDer));
+ x509.signCert(privKey, WolfSSL.RSAk,
+ WolfSSL.SSL_FILETYPE_ASN1, "SHA256");
+
+ /* Output to DER and PEM */
+ byte[] derCert = x509.getDer();
+ byte[] pemCert = x509.getPem();
+
+ assertNotNull(derCert);
+ assertTrue(derCert.length > 0);
+ assertNotNull(pemCert);
+ assertTrue(pemCert.length > 0);
+
+ /* Sanity check generated cert buffers */
+ sanityCheckCertFileBytes(derCert, WolfSSL.SSL_FILETYPE_ASN1);
+ sanityCheckCertFileBytes(pemCert, WolfSSL.SSL_FILETYPE_PEM);
+
+ /* Sanity check CertManager can verify signature using expected CA */
+ verifyCertSignatureIsCorrect(derCert, WolfSSL.SSL_FILETYPE_ASN1,
+ null, 0, issuer.getDer(), WolfSSL.SSL_FILETYPE_ASN1);
+ verifyCertSignatureIsCorrect(pemCert, WolfSSL.SSL_FILETYPE_PEM,
+ null, 0, issuer.getDer(), WolfSSL.SSL_FILETYPE_ASN1);
+
+ /* Free native memory */
+ subjectName.free();
+ x509.free();
+
+ System.out.println("\t\t... passed");
+ }
+
+ /* Test self-signed certificate generation using higher-level Java classes
+ * for public key, issuer name, and issuer private key */
+ private void testCertGen_SelfSigned_UsingJavaClasses()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException, NoSuchAlgorithmException {
+
+ System.out.print("\tself signed (Java classes)");
+
+ WolfSSLCertificate x509 = new WolfSSLCertificate();
+ assertNotNull(x509);
+
+ /* Set notBefore/notAfter dates */
+ Instant now = Instant.now();
+ final Date notBefore = Date.from(now);
+ final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
+ x509.setNotBefore(notBefore);
+ x509.setNotAfter(notAfter);
+
+ /* Set serial number */
+ x509.setSerialNumber(BigInteger.valueOf(12345));
+
+ /* Set Subject Name */
+ WolfSSLX509Name subjectName = GenerateTestSubjectName();
+ assertNotNull(subjectName);
+ x509.setSubjectName(subjectName);
+
+ /* Not setting Issuer, since generating self-signed cert */
+
+ /* Set Public Key from generated java.security.PublicKey */
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ kpg.initialize(2048);
+ KeyPair keyPair = kpg.generateKeyPair();
+ PublicKey pubKey = keyPair.getPublic();
+ x509.setPublicKey(pubKey);
+
+ /* Set Extensions */
+ if (WolfSSL.getLibVersionHex() > 0x05006003) {
+ /* Key Usage and Extended Key Usage only work with wolfSSL
+ * later than 5.6.3 */
+ x509.addExtension(WolfSSL.NID_key_usage,
+ "digitalSignature,keyEncipherment,dataEncipherment", false);
+ x509.addExtension(WolfSSL.NID_ext_key_usage,
+ "clientAuth,serverAuth", false);
+ }
+ x509.addExtension(WolfSSL.NID_subject_alt_name,
+ "test.wolfssl.com", false);
+ x509.addExtension(WolfSSL.NID_basic_constraints, true, true);
+
+ /* Sign cert, self-signed with java.security.PrivateKey */
+ PrivateKey privKey = keyPair.getPrivate();
+ x509.signCert(privKey, "SHA256");
+
+ /* Output to DER and PEM */
+ byte[] derCert = x509.getDer();
+ byte[] pemCert = x509.getPem();
+
+ assertNotNull(derCert);
+ assertTrue(derCert.length > 0);
+ assertNotNull(pemCert);
+ assertTrue(pemCert.length > 0);
+
+ /* Sanity check generated cert buffers */
+ sanityCheckCertFileBytes(derCert, WolfSSL.SSL_FILETYPE_ASN1);
+ sanityCheckCertFileBytes(pemCert, WolfSSL.SSL_FILETYPE_PEM);
+
+ /* Sanity check CertManager can verify signature using expected CA */
+ verifyCertSignatureIsCorrect(derCert, WolfSSL.SSL_FILETYPE_ASN1,
+ null, 0, derCert, WolfSSL.SSL_FILETYPE_ASN1);
+ verifyCertSignatureIsCorrect(pemCert, WolfSSL.SSL_FILETYPE_PEM,
+ null, 0, derCert, WolfSSL.SSL_FILETYPE_ASN1);
+
+ /* Free native memory */
+ subjectName.free();
+ x509.free();
+
+ System.out.println("\t... passed");
+ }
+
+ /* Test CA-signed certificate generation using higher-level Java classes
+ * for public key, issuer name, and issuer private key */
+ private void testCertGen_CASigned_UsingJavaClasses()
+ throws WolfSSLException, WolfSSLJNIException, IOException,
+ CertificateException, NoSuchAlgorithmException,
+ InvalidKeySpecException {
+
+ System.out.print("\tCA signed (Java classes)");
+
+ WolfSSLCertificate x509 = new WolfSSLCertificate();
+ assertNotNull(x509);
+
+ /* Set notBefore/notAfter dates */
+ Instant now = Instant.now();
+ final Date notBefore = Date.from(now);
+ final Date notAfter = Date.from(now.plus(Duration.ofDays(365)));
+ x509.setNotBefore(notBefore);
+ x509.setNotAfter(notAfter);
+
+ /* Set serial number */
+ x509.setSerialNumber(BigInteger.valueOf(12345));
+
+ /* Set Subject Name */
+ WolfSSLX509Name subjectName = GenerateTestSubjectName();
+ assertNotNull(subjectName);
+ x509.setSubjectName(subjectName);
+
+ /* Set Issuer Name from existing PEM file, using server cert since it
+ * is a CA, and wolfSSL proper ships a PKCS#8 encoded DER private key
+ * needed below */
+ WolfSSLCertificate issuer =
+ new WolfSSLCertificate(Files.readAllBytes(Paths.get(caCertPem)),
+ WolfSSL.SSL_FILETYPE_PEM);
+ X509Certificate issuerX509 = issuer.getX509Certificate();
+ x509.setIssuerName(issuerX509);
+
+ /* Set Public Key from generated java.security.PublicKey */
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+ kpg.initialize(2048);
+ KeyPair keyPair = kpg.generateKeyPair();
+ PublicKey pubKey = keyPair.getPublic();
+ x509.setPublicKey(pubKey);
+
+ /* Set Extensions */
+ if (WolfSSL.getLibVersionHex() > 0x05006003) {
+ /* Key Usage and Extended Key Usage only work with wolfSSL
+ * later than 5.6.3 */
+ x509.addExtension(WolfSSL.NID_key_usage,
+ "digitalSignature,keyEncipherment,dataEncipherment", false);
+ x509.addExtension(WolfSSL.NID_ext_key_usage,
+ "clientAuth,serverAuth", false);
+ }
+ x509.addExtension(WolfSSL.NID_subject_alt_name,
+ "test.wolfssl.com", false);
+ x509.addExtension(WolfSSL.NID_basic_constraints, false, true);
+
+ /* Sign cert, with CA's private key */
+ byte[] privBytes = Files.readAllBytes(Paths.get(caKeyPkcs8Der));
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privBytes);
+ RSAPrivateKey rsaPriv = (RSAPrivateKey)kf.generatePrivate(spec);
+ x509.signCert((PrivateKey)rsaPriv, "SHA256");
+
+ /* Output to DER and PEM */
+ byte[] derCert = x509.getDer();
+ byte[] pemCert = x509.getPem();
+
+ assertNotNull(derCert);
+ assertTrue(derCert.length > 0);
+ assertNotNull(pemCert);
+ assertTrue(pemCert.length > 0);
+
+ /* Sanity check generated cert buffers */
+ sanityCheckCertFileBytes(derCert, WolfSSL.SSL_FILETYPE_ASN1);
+ sanityCheckCertFileBytes(pemCert, WolfSSL.SSL_FILETYPE_PEM);
+
+ /* Sanity check CertManager can verify signature using expected CA */
+ verifyCertSignatureIsCorrect(derCert, WolfSSL.SSL_FILETYPE_ASN1,
+ null, 0, issuer.getDer(), WolfSSL.SSL_FILETYPE_ASN1);
+ verifyCertSignatureIsCorrect(pemCert, WolfSSL.SSL_FILETYPE_PEM,
+ null, 0, issuer.getDer(), WolfSSL.SSL_FILETYPE_ASN1);
+
+ /* Free native memory */
+ subjectName.free();
+ x509.free();
+
+ System.out.println("\t... passed");
+ }
+
+ /* Utility method if needed for testing, print out cert array to file */
+ private void writeOutCertFile(byte[] cert, String path)
+ throws IOException {
+ Files.write(new File(path).toPath(), cert);
+ }
}
+
diff --git a/src/test/com/wolfssl/test/WolfSSLTest.java b/src/test/com/wolfssl/test/WolfSSLTest.java
index 353a006..cb183c3 100644
--- a/src/test/com/wolfssl/test/WolfSSLTest.java
+++ b/src/test/com/wolfssl/test/WolfSSLTest.java
@@ -52,6 +52,7 @@ public class WolfSSLTest {
test_WolfSSL_new(lib);
test_WolfSSL_protocol();
test_WolfSSL_Method_Allocators(lib);
+ test_WolfSSL_getLibVersionHex();
testGetCiphersAvailableIana();
}
@@ -128,5 +129,17 @@ public class WolfSSLTest {
System.out.println("\t... passed");
}
+
+ public void test_WolfSSL_getLibVersionHex() {
+ System.out.print("\tgetLibVersionHex()");
+
+ long verHex = WolfSSL.getLibVersionHex();
+ if (verHex == 0 || verHex < 0) {
+ System.out.println("\t\t... failed");
+ fail("getting library version hex failed");
+ }
+
+ System.out.println("\t\t... passed");
+ }
}