wolfcrypt-jni/examples/provider/WolfSSLKeyStoreExample.java

277 lines
10 KiB
Java

/* WolfSSLKeyStoreExample.java
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.nio.file.Files;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Security;
import java.security.SecureRandom;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.KeyFactory;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import com.wolfssl.provider.jce.WolfCryptProvider;
public class WolfSSLKeyStoreExample {
/* KeyStore password */
static String storePass = "wolfsslpassword";
/* KeyStore output file */
static String wksFile = "wolfssl.wks";
/* KeyStore type */
static String storeType = "WKS";
/* RSA server cert and private key */
static String serverCertRsaDer = "../../certs/server-cert.der";
static String serverRsaPkcs8Der = "../../certs/server-keyPkcs8.der";
/* ECC server cert and private key */
static String serverCertEccDer = "../../certs/server-ecc.der";
static String serverEccPkcs8Der = "../../certs/ecc-keyPkcs8.der";
/* RSA server cert chain */
static String intRsaServerCertDer =
"../../certs/intermediate/server-int-cert.pem";
static String intRsaInt1CertDer =
"../../certs/intermediate/ca-int-cert.pem";
static String intRsaInt2CertDer =
"../../certs/intermediate/ca-int2-cert.pem";
/* ECC server cert chain */
static String intEccServerCertDer =
"../../certs/intermediate/server-int-ecc-cert.der";
static String intEccInt1CertDer =
"../../certs/intermediate/ca-int-ecc-cert.der";
static String intEccInt2CertDer =
"../../certs/intermediate/ca-int2-ecc-cert.der";
/**
* Create and return PrivateKey object from file path to DER-encoded
* private key file.
*
* @param derFilePath file path to DER-encoded PKCS#8 private key file
* @param alg algorithm for KeyFactory instance (ex: "RSA", "EC")
*
* @return PrivateKey object created from file path given
*
* @throws IllegalArgumentException on bad argument or processing of arg
* @throws IOException on error converting File to Path
* @throws NoSuchAlgorithmException on bad "alg" when getting KeyFactory
* @throws InvalidKeySpecException on error generating PrivateKey object
* @throws Exception on other error
*/
private static PrivateKey DerFileToPrivateKey(String derFilePath,
String alg) throws IllegalArgumentException, IOException,
NoSuchAlgorithmException, InvalidKeySpecException,
InvalidKeySpecException {
byte[] fileBytes = null;
PKCS8EncodedKeySpec spec = null;
KeyFactory kf = null;
PrivateKey key = null;
if (derFilePath == null || derFilePath.isEmpty()) {
throw new IllegalArgumentException(
"Input DER file path is null or empty");
}
fileBytes = Files.readAllBytes(new File(derFilePath).toPath());
if (fileBytes == null || fileBytes.length == 0) {
throw new IllegalArgumentException(
"Bytes read from DER file is null or empty, bad file path?");
}
spec = new PKCS8EncodedKeySpec(fileBytes);
if (spec == null) {
throw new InvalidKeySpecException(
"Unable to create PKCS8EncodedKeySpec");
}
kf = KeyFactory.getInstance(alg);
key = kf.generatePrivate(spec);
return key;
}
/**
* Read in and convert certificate file to Certificate object.
*
* @param certPath path to DER-encoded certificate file
*
* @return new Certificate object representing certPath file
*
* @throws FileNotFoundException on error reading certPath file
* @throws CertificateException on error geting CertificateFactory or
* generating Certificate object
*/
private static Certificate CertFileToCertificate(String certPath)
throws FileNotFoundException, CertificateException {
CertificateFactory cf = null;
Certificate cert = null;
cf = CertificateFactory.getInstance("X.509");
cert = cf.generateCertificate(new FileInputStream(certPath));
return cert;
}
public static void InsertKeyStoreEntries(KeyStore store)
throws FileNotFoundException, KeyStoreException, IOException,
CertificateException, NoSuchAlgorithmException,
InvalidKeySpecException {
byte[] fileBytes = null;
PrivateKey privKey = null;
Certificate cert = null;
Certificate[] chain = null;
KeyGenerator kg = null;
SecretKey aesKey = null;
/* INSERT [1]: RSA cert only */
cert = CertFileToCertificate(serverCertRsaDer);
store.setCertificateEntry("serverRsa", cert);
/* INSERT [2]: RSA priv key + single cert */
privKey = DerFileToPrivateKey(serverRsaPkcs8Der, "RSA");
store.setKeyEntry("rsaCert", privKey,
storePass.toCharArray(), new Certificate[] { cert });
/* INSERT [5]: RSA priv key + cert chain */
chain = new Certificate[3];
cert = CertFileToCertificate(intRsaServerCertDer);
chain[0] = cert;
cert = CertFileToCertificate(intRsaInt2CertDer);
chain[1] = cert;
cert = CertFileToCertificate(intRsaInt1CertDer);
chain[2] = cert;
store.setKeyEntry("rsaChain", privKey, storePass.toCharArray(), chain);
/* INSERT [3]: ECC cert only */
cert = CertFileToCertificate(serverCertEccDer);
store.setCertificateEntry("serverEcc", cert);
/* INSERT [4]: ECC priv key + single cert */
privKey = DerFileToPrivateKey(serverEccPkcs8Der, "EC");
store.setKeyEntry("eccCert", privKey,
storePass.toCharArray(), new Certificate[] { cert });
/* INSERT [6]: ECC priv key + cert chain */
chain = new Certificate[3];
cert = CertFileToCertificate(intEccServerCertDer);
chain[0] = cert;
cert = CertFileToCertificate(intEccInt2CertDer);
chain[1] = cert;
cert = CertFileToCertificate(intEccInt1CertDer);
chain[2] = cert;
store.setKeyEntry("eccChain", privKey, storePass.toCharArray(), chain);
/* INSERT [7]: AES SecretKey */
/* If running this example with JKS type, JKS cannot import
* non-private keys. Only do for WKS type. */
if (storeType.equals("WKS")) {
kg = KeyGenerator.getInstance("AES");
kg.init(256, new SecureRandom());
aesKey = kg.generateKey();
store.setKeyEntry("aesKey", aesKey, storePass.toCharArray(), null);
}
}
public static void WriteKeyStoreToFile(KeyStore store)
throws FileNotFoundException, KeyStoreException, IOException,
NoSuchAlgorithmException, CertificateException {
FileOutputStream fos = new FileOutputStream(wksFile);
store.store(fos, storePass.toCharArray());
fos.close();
}
public static KeyStore ReadKeyStoreFromFile(String fileName)
throws KeyStoreException, FileNotFoundException, IOException,
NoSuchAlgorithmException, CertificateException {
KeyStore store = null;
store = KeyStore.getInstance(storeType);
store.load(new FileInputStream(fileName), storePass.toCharArray());
return store;
}
public static void main(String args [])
{
KeyStore store = null;
Provider p = null;
System.out.println("WolfSSLKeyStore (WKS) Example App\n");
/* Install wolfJCE */
Security.insertProviderAt(new WolfCryptProvider(), 1);
try {
store = KeyStore.getInstance(storeType);
store.load(null, storePass.toCharArray());
p = store.getProvider();
System.out.println("KeyStore('" + storeType + "') provider = " + p);
/* Insert variety of entry types */
System.out.println("\n-------------------------------------------");
System.out.println("Inserting entries into KeyStore");
System.out.println("-------------------------------------------");
InsertKeyStoreEntries(store);
/* Store KeyStore to file (wolfssl.wks) */
System.out.println("\n-------------------------------------------");
System.out.println("Writing KeyStore to file: " + wksFile);
System.out.println("-------------------------------------------");
WriteKeyStoreToFile(store);
/* Read KeyStore back in from file */
System.out.println("\n-------------------------------------------");
System.out.println("Reading KeyStore in from file: " + wksFile);
System.out.println("-------------------------------------------");
store = ReadKeyStoreFromFile(wksFile);
System.out.println("\nExample Finished Successfully");
} catch (Exception e) {
e.printStackTrace();
}
}
}