JCE: add WolfSSLKeyStore (WKS) KeyStore implementation

pull/67/head
Chris Conlon 2024-01-24 17:49:25 -07:00
parent a5f62b3893
commit 8f254f67b3
67 changed files with 5966 additions and 135 deletions

5
.gitignore vendored
View File

@ -4,7 +4,7 @@ build/
lib/ lib/
# Generated Javadocs # Generated Javadocs
docs/ docs/javadoc
# makefile, since copied from makefile.linux or makefile.macosx # makefile, since copied from makefile.linux or makefile.macosx
makefile makefile
@ -31,3 +31,6 @@ infer-out/
# Maven output directory # Maven output directory
target/ target/
# Generated system cacerts.wks and jssecacerts.wks
examples/certs/systemcerts/cacerts.wks
examples/certs/systemcerts/jssecacerts.wks

View File

@ -21,6 +21,31 @@ and Android platforms.
Pre-compiled and signed wolfCrypt JNI/JCE JAR's are included with the stable Pre-compiled and signed wolfCrypt JNI/JCE JAR's are included with the stable
releases of the JCE provider. See below for more details. releases of the JCE provider. See below for more details.
### System and Security Property Support
---------
wolfJCE supports the following System and Security properties for behavior
customization and debugging.
#### Security Property Support
The following Java Security properties can be set in the `java.security`
file for JCE provider customization:
| Security Property | Default | To Enable | Description |
| --- | --- | --- | --- |
| wolfjce.wks.iterationCount | 210,000 | Numeric | PBKDF2 iteration count (10,000 minimum) |
| wolfjce.wks.maxCertChainLength | 100 | Integer | Max cert chain length |
#### System Property Support
The following Java System properties can be set on the command line or
programatically for JCE provider customization:
| System Property | Default | To Enable | Description |
| --- | --- | --- | --- |
| wolfjce.debug | "false" | "true" | Enable wolfJCE debug logging |
### Algorithm Support: ### Algorithm Support:
--------- ---------
@ -87,6 +112,9 @@ The JCE provider currently supports the following algorithms:
PBKDF2WithHmacSHA3-384 PBKDF2WithHmacSHA3-384
PBKDF2WithHmacSHA3-512 PBKDF2WithHmacSHA3-512
KeyStore
WKS
### SecureRandom.getInstanceStrong() ### SecureRandom.getInstanceStrong()
When registered as the highest priority security provider, wolfJCE will provide When registered as the highest priority security provider, wolfJCE will provide
@ -104,6 +132,104 @@ securerandom.strongAlgorithms=HashDRBG:wolfJCE
Note that the `securerandom.source` property in `java.security` has no affect Note that the `securerandom.source` property in `java.security` has no affect
on the wolfJCE provider. on the wolfJCE provider.
### WolfSSLKeyStore (WKS) Implementation Details and Usage
wolfJCE implements one custom KeyStore class named WolfSSLKeyStore, represented
as "WKS". If wolfJCE has been installed as a Security provider, this KeyStore
can be used with:
```
KeyStore store = KeyStore.getInstance("WKS");
```
#### Algorithm Use and FIPS 140-2 / 140-3 Compatibility
The WKS KeyStore has been designed to be compatible with wolfCrypt
FIPS 140-2 and 140-3.
PrivateKey and SecretKey objects stored are protected inside the KeyStore
using AES-CBC-256 with HMAC-SHA512 in an Encrypt-then-MAC manner. PKCS#5
PBKDF2-HMAC-SHA512 is used to generate 96 bytes of key material which is split
between a 32-byte AES-CBC-256 key and 64-byte HMAC-SHA512 key.
PBKDF2 salt is 16 bytes, randomly generated for each key storage operation
PBKDF2 iteration count defaults to 210,000 (current OWASP recommendation), but
is user overridable with wolfjce.wks.iterationCount Security property in
java.security file. User password is converted from char[] to byte[] using
UTF-8, consistent with how SunJCE uses UTF-8 for PBKDF2 SecretKeyFactory.
AES-CBC IV is randomly generated for each key storage operation
This KeyStore uses a different format that is not directly compatible with
existing formats (ex: JKS, PKCS12, etc). Other KeyStore types will need to be
converted over to WKS KeyStore objects for FIPS compliant use with wolfCrypt
FIPS 140-2/3.
#### Stored Object Compatibility
The WKS KeyStore supports storage of PrivateKey, Certificate, and
SecretKey objects.
#### Converting Other KeyStore Formats to WKS
The Java `keytool` application can be used to convert between KeyStore formats.
This can be easily used for example to convert a JKS KeyStore into a WKS
format KeyStore.
The following example command would convert a KeyStore in JKS format named
`server.jks` to a KeyStore in WKS format named `server.wks`:
```
keytool -importkeystore -srckeystore server.jks -destkeystore server.wks \
-srcstoretype JKS -deststoretype WKS \
-srcstorepass "pass" -deststorepass "pass" \
-provider com.wolfssl.provider.jce.WolfCryptProvider \
--providerpath /path/to/wolfcrypt-jni.jar
```
To list entries inside a WKS keystore using the `keytool`, a command
similar to the following can be used (with the `-list` option):
```
keytool -list -provider com.wolfssl.provider.jce.WolfCryptProvider \
--providerpath /path/to/wolfcrypt-jni.jar \
-storetype WKS -storepass "pass" -keystore server.wks
```
If running the above commands gives an error about the native wolfcryptjni
shared library not being found, you may need to add the library location
to `LD_LIBRARY_PATH` (Linux) or `DYLD_LIBRARY_PATH` (Mac OSX), ie:
```
export LD_LIBRARY_PATH=/path/to/libwolfcryptjni.so:$LD_LIBRARY_PATH
```
#### Converting System cacerts to WKS Format KeyStore
For FIPS compatibility, users who do not want to use non-wolfSSL KeyStore
implementations (ex: JKS) may need to convert the system cacerts or
jssecacerts KeyStore to WKS format. This can be done using the keytool
command as described above (default password for cacerts is 'changeit'), or
the helper script located in this package at:
```
examples/certs/systemcerts/system-cacerts-to-wks.sh
```
This is a shell script that takes no arguments. It tries to detect the
location of the active Java installation and converts `cacerts` and/or
`jssecacerts` to WKS format if they are found. Converted KeyStores are placed
under the same directory as the script, specifically:
```
examples/certs/systemcerts/cacerts.wks
examples/certs/systemcerts/jssecacerts.wks
```
#### Design Notes
More complete design documentation can be found in
[docs/WolfSSLKeyStore.md](./docs/design/WolfSSLKeyStore.md).
### Example / Test Code ### Example / Test Code
--------- ---------

View File

@ -26,7 +26,7 @@
<property name="jni.dir" value="jni/include/" /> <property name="jni.dir" value="jni/include/" />
<property name="lib.dir" value="lib/" /> <property name="lib.dir" value="lib/" />
<property name="build.dir" value="build" /> <property name="build.dir" value="build" />
<property name="doc.dir" value="docs" /> <property name="doc.dir" value="docs/javadoc" />
<property name="test.dir" value="src/test/java/" /> <property name="test.dir" value="src/test/java/" />
<property name="test.build.dir" value="build/test" /> <property name="test.build.dir" value="build/test" />
<property name="reports.dir" value="build/reports" /> <property name="reports.dir" value="build/reports" />
@ -86,6 +86,9 @@
<delete failonerror="false"> <delete failonerror="false">
<fileset dir="${lib.dir}" includes="wolfcrypt-jni.jar" /> <fileset dir="${lib.dir}" includes="wolfcrypt-jni.jar" />
</delete> </delete>
<delete includeemptydirs="true" failonerror="false">
<fileset dir="${doc.dir}" includes="**/*"/>
</delete>
</target> </target>
<!-- set javac flags: debug jar, no optimization, all debug symbols --> <!-- set javac flags: debug jar, no optimization, all debug symbols -->
@ -111,6 +114,7 @@
<target name="init" depends="clean, debug-javac-flags, release-javac-flags"> <target name="init" depends="clean, debug-javac-flags, release-javac-flags">
<mkdir dir="${build.dir}" /> <mkdir dir="${build.dir}" />
<mkdir dir="${lib.dir}" /> <mkdir dir="${lib.dir}" />
<mkdir dir="${doc.dir}" />
<mkdir dir="${test.build.dir}" /> <mkdir dir="${test.build.dir}" />
<mkdir dir="${reports.dir}" /> <mkdir dir="${reports.dir}" />
<mkdir dir="${examples.provider.build.dir}" /> <mkdir dir="${examples.provider.build.dir}" />

View File

@ -0,0 +1,256 @@
# wolfSSL KeyStore (WKS) Design Notes
The WKS KeyStore format was designed to be compatible with wolfCrypt FIPS
140-2 and 140-3, meaning it utilizes FIPS validated cryptographic algorithms.
This document includes notes on the design and algorithm choices used by WKS.
For details on the wolfCrypt FIPS 140-2/3 cryptographic module and boundary,
please reference the appropriate Security Policy or contact fips@wolfssl.com.
## User Customizable Properties
| Security Property | Default | Min | Description |
| --- | --- | --- | --- |
| `wolfjce.wks.iterationCount` | 210,000 | 10,000 | PBKDF2 iteration count |
| `wolfjce.wks.maxCertChainLength` | 100 | N/A | Max cert chain length |
## Notes on Algorithm and Security Properties
PBKDF2-HMAC-SHA512 was chosen over PBKDF2-HMAC-SHA256 for AES and HMAC key
generation to allow use of fewer iterations (210,000, as per current
[OWASP recommendations](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2)) versus the recommended 600,000 for SHA-256.
PBKDF2 salt size of 128-bits (16 bytes) is used to follow recommendations
in [NIST SP 800-132, Page 6](https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf).
AES-CBC (AES/CBC/PKCS5Padding) was chosen over AES-GCM since AES-GCM requires
that each {key,nonce} combination be unique. Simply generating a random nonce
via RNG does not guarantee uniqueness, and we have no way of maintaining an
accurate counter across KeyStore objects and store/load operations.
Different keys are used for PrivateKey/SecretKey encryption and HMAC, and
derived from one larger PBKDF2 operation (96 bytes) then split between
encryption (32-byte key) and HMAC (64-byte key) operations. A
random salt is generated for each PBKDF2 key generation operation.
HMAC values are calculated over content but also the PBKDF2 salt length,
salt, and iteration count, and all other key parameters (ex: IV and length) to
also include those in the integrity check.
## KeyStore Integrity
### HMAC Generation During KeyStore Storage
When WKS KeyStore objects are stored (`engineStore()`), the following format
is used. This is composed of a *HEADER* section, an *ENTRIES* section, followed
lastly by an HMAC generated over the *HEADER* and *ENTRIES*, including the
PBKDF2 salt, salt length, and iteration count.
The *HEADER* includes a magic number specific to the WKS KeyStore type (`7`), a
WKS KeyStore version (may be incremented in the future as features are added
or if the WKS type definition changes), and a count of the entries included in
the store.
The *ENTRIES* section is made up of one or more `WKSPrivateKey`,
`WKSSecretKey`, or `WKSCertificate` entries. These represent the storage of
a `PrivateKey`, `SecretKey`, and `Certificate` objects respectively.
Generation of the HMAC happens during a call to
`engineStore(OutputStream stream, char[] password)` and is generated in the
following manner:
- Input password must not be null or zero length
- Input password is converted from `char[]` into `byte[]` using password
conversion algorithm described below.
- Random salt of size `WKS_PBKDF2_SALT_SIZE` (128 bits) is generated
- HMAC-SHA512 key (64-bytes) is generated with PBKDF2-HMAC-SHA512 using:
+ Password byte array
+ Random 16-byte salt (`WKS_PBKDF2_SALT_SIZE`)
+ 210,000 iterations (`WKS_PBKDF2_ITERATION_COUNT`), but can be overriden
by user by setting `wolfjce.wks.iterationCount` Security property.
Minimum iteration count is 10,000.
- The final HMAC-SHA512 is calculated using the derived key over the bytes of
*HEADER*, *ENTRIES*, salt length, salt, and iteration count. It is then
written out to the OutputStream.
### HMAC Verification During KeyStore Load
When a WKS KeyStore is loaded with
`engineLoad(InputStream stream, char[] password)`, the input password is
optional. If a password is provided, the KeyStore integrity will be checked
using the included HMAC, otherwise the integrity check will be skipped.
This design is to maintain consistency with how the Java JKS format handles
integrity checks upon KeyStore load, and allows for easy conversion and use
of files such as `cacerts` to a WKS type where users do not normally provide
the password when loading the KeyStore file.
Since the HMAC is stored at the end of the KeyStore stream, `engineLoad()`
buffers KeyStore bytes as they are read in, up to and including the PBKDF2
salt size, salt, and PBKDF2 iteration count. Once all entries have been read,
the HMAC is read and verified:
- The salt length is read, sanitized against `WKS_PBKDF2_SALT_SIZE`
- The salt is read
- The PBKDF2 iteration count is read, and checked against min size of
`WKS_PBKDF2_MIN_ITERATIONS`
- Caching of data is paused while the HMAC is read in next
- The original HMAC length is read
- An HMAC-SHA512 is regenerated over the buffered header and entry bytes
+ Password is converted from char[] to byte[] as explained below
+ An HMAC-SHA512 key (64-bytes) is calculated as explained above, using
salt that was read from input KeyStore stream
+ The generated HMAC value is calculated using this key
- The generated HMAC is compared in both size and contents against the stored
HMAC. If these are different, an IOException is thrown.
### Stored WKS format:
```
* HEADER:
* magicNumber (int / 7)
* keystoreVersion (int)
* entryCount (int)
* ENTRIES (can be any of below, depending on type)
* [WKSPrivateKey]
* entryId (int / 1)
* alias (UTF String)
* creationDate.getTime() (long)
* kdfSalt.length (int)
* kdfSalt (byte[])
* kdfIterations (int)
* iv.length (int)
* iv (byte[])
* encryptedKey.length (int)
* encryptedKey (byte[])
* chain.length (int)
* FOR EACH CERT:
* chain[i].getType() (UTF String)
* chain[i].getEncoded().length (int)
* chain[i].getEncoced() (byte[])
* hmac.length (int)
* hmac (HMAC-SHA512) (byte[])
* [WKSSecretKey]
* entryId (int / 3)
* alias (UTF String)
* creationDate.getTime() (long)
* key.getAlgorithm() (UTF String)
* kdfSalt.length (int)
* kdfIterations (int)
* kdfSalt (byte[])
* iv.length (int)
* iv (byte[])
* encryptedKey.length (int)
* encryptedKey (byte[])
* hmac.length (int)
* hmac (HMAC-SHA512) (byte[])
* [WKSCertificate]
* entryId (int / 2)
* alias (UTF String)
* creationDate.getTime() (long)
* cert.getType() (UTF String)
* cert.getEncoded().length (int)
* cert.getEncoced() (byte[])
* HMAC PBKDF2 salt length int
* HMAC PBKDF2 salt (byte[])
* HMAC PBKDF2 iterations int
* HMAC length int
* HMAC (HMAC-SHA512) (byte[])
```
## PrivateKey Protection
A PrivateKey entry is stored into the KeyStore with the `engineSetKeyEntry()`
method, exposed publicly through `KeyStore` as `setKeyEntry()`, when
passing in a `Key` of type `PrivateKey`. The password argument is not allowed
to be null, otherwise a KeyStoreException is thrown.
```
void setKeyEntry(String alias, Key key, char[] password, Certificate[] chain)
```
Process of storing a PrivateKey is as follows:
- Sanity check the certificate chain:
+ Chain is not null or zero length chain
+ Chain is made up of X509Certificate objects
+ Chain cert signatures are correct as we walk up the chain. The cert
chain should be ordered from leaf cert (entity) to top-most intermedate
certificate. The last cert is loaded as a trusted root, and used to
verify the rest of the chain, since we don't have the root CA cert
available at this point.
- Verify private key (`Key key`) matches the leaf certificate (`chain[0]`)
- Encrypt private key before storing into KeyStore map:
+ Generate random PBKDF2 salt, of size `WKS_PBKDF2_SALT_SIZE` bytes
+ Generate random IV, of size `WKS_ENC_IV_LENGTH` bytes
+ Convert password from char[] into byte[] using password conversion
algorithm described below.
+ Encryption key is derived using PBKDF2-SHA256 using byte array, random
salt, and `WKS_PBKDF2_ITERATION_COUNT` (or customized) iteration count.
- 96-byte key is generated with PBKDF2 in total, split between 32-byte
AES-CBC-256 and 64-byte HMAC-SHA512 keys.
+ Encrypt key bytes using AES-CBC-256
+ Generate HMAC-SHA512 over encrypted key and other WKSPrivateKey
object members
+ Zeroize KEK and HMAC keys (generated from PBKDF2)
When importing a PrivateKey from a KeyStore stream, the process is reversed.
Initially during `engineLoad()`, parameters are read in as well as the encrypted
key:
- Read PBKDF2 salt length, sanity check against `WKS_PBKDF2_SALT_SIZE`
- Read PBKDF2 salt
- Read PBKDF2 iterations, sanity check against `WKS_PBKDF2_MIN_ITERATIONS`
- Read encryption IV, santiy check against `WKS_ENC_IV_LENGTH`
- Read encrypted key
- Read certificate chain if present, check length against `WKS_MAX_CHAIN_COUNT`
- Read HMAC value into object variable, will be checked when user gets key out
The PrivateKey is stored encrypted internal to the WolfSSLKeyStore until
a caller retrieves it with `getKey()`. At that point, WolfSSLKeyStore:
- Derives the decryption key using PBKDF2-SHA256
+ Converts password from `char[]` to `byte[]` using algorithm below
+ Uses salt and iteration count stored internally from encryption
process or read from KeyStore stream after loading
+ Derives decryption key and HMAC key with PBKDF2-HMAC-SHA512
+ Regenerate and verify HMAC against stored value
+ Decrypts key using AES-CBC-256
+ Zeroizes KEK and HMAC keys (generated from PBKDF2)
## SecretKey Protection
A SecretKey entry is stored into the KeyStore with the `engineSetKeyEntry()`
method, exposed publicly through `KeyStore` as `setKeyEntry()`, when
passing in a `Key` of type `SecretKey`. The password argument is not allowed
to be null, otherwise a KeyStoreException is thrown.
```
void setKeyEntry(String alias, Key key, char[] password, Certificate[] chain)
```
Process of storing a SecretKey is the same as PrivateKey above, except
there is no certificate so no certifiate or private key sanity checks are done.
The same encrypt/decrypt process is shared between PrivateKey and SecretKey
protection.
## Certificate Protection
A Certificate entry is stored into the KeyStore with the
`engineSetCertificateEntry()` method. Certificate entries are not protected
and are stored directly into the KeyStore.
They are integrity protected by the KeyStore HMAC when a KeyStore is written
out to a stream with `engineStore()`, but otherwise have no internal
encryption or integrity protection since no password is provided when storing
certificates.
## Password Conversion Algorithm
The Java KeyStore class specifies that passwords are provided by the user as a
Java character array (`char[]`). Before using a password as input to PBKDF2,
wolfJCE is converts it into a byte array. In Java, one character (`char`) is
composed of two bytes (`byte`). RFC 2898 (PBKDF2) considers a password to be an
octet string and recommends for interop ASCII or UTF-8 encoding be used. SunJCE
uses UTF-8 for PBKDF2 SecretKeyFactory, so we do the same in WolfSSLKeyStore
using `WolfCryptSecretKeyFactory.passwordToByteArray(char[])`.
# Support
Please email support@wolfssl.com with any questions.

View File

@ -26,18 +26,28 @@ the example Java KeyStore files, see the next section.
## Updating Example Java KeyStore Files ## Updating Example Java KeyStore Files
To update the example Java KeyStore files, use the provided `update-jks.sh` To update the example Java KeyStore files, use the provided `update-jks-wks.sh`
bash script. This script requires one argument on the command line which is bash script. This script requires one argument on the command line which is
the location of the wolfSSL proper certs directory. the location of the wolfSSL proper certs directory.
This script will create new KeyStore files from original certificates. It will
first create JKS KeyStore files, then convert those to WKS (WolfSSLKeyStore)
format.
``` ```
$ cd wolfcryptjni/examples/certs $ cd wolfcryptjni/examples/certs
$ ./update-jks.sh /path/to/wolfssl/certs $ ./update-jks-wks.sh /path/to/wolfssl/certs
``` ```
This script only updates the example .jks files and not the individual This script only updates the example .jks and .wks files and not the individual
.pem or .der files in this directory. For that, please see the above section. .pem or .der files in this directory. For that, please see the above section.
## Testing that Java keytool can read/parse WKS files
To confirm that Java keytool can parse WolfSSLKeyStore (WKS) format stores OK,
the `keytool-print-wks.sh` script can be used. This will call `keytool -list`
on each WKS KeyStore which is expected to pass successfully.
## Support ## Support
Please contact the wolfSSL support team at support@wolfssl.com with any Please contact the wolfSSL support team at support@wolfssl.com with any

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -2,41 +2,41 @@ Certificate Revocation List (CRL):
Version 2 (0x1) Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_2048, OU = Programming-2048, CN = www.wolfssl.com, emailAddress = info@wolfssl.com Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_2048, OU = Programming-2048, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Last Update: Dec 13 22:19:33 2023 GMT Last Update: Jan 9 00:34:30 2024 GMT
Next Update: Sep 8 22:19:33 2026 GMT Next Update: Oct 5 00:34:30 2026 GMT
CRL extensions: CRL extensions:
X509v3 CRL Number: X509v3 CRL Number:
8 8
Revoked Certificates: Revoked Certificates:
Serial Number: 02 Serial Number: 02
Revocation Date: Dec 13 22:19:33 2023 GMT Revocation Date: Jan 9 00:34:30 2024 GMT
Signature Algorithm: sha256WithRSAEncryption Signature Algorithm: sha256WithRSAEncryption
74:17:9b:40:81:d2:a0:f3:26:68:44:5b:f8:a2:6c:3f:7e:71: 52:11:97:57:04:d7:e2:14:1f:c4:7f:a2:d8:cf:4c:b7:5b:0c:
75:a2:7f:c6:e6:71:cb:f9:08:57:42:cd:3e:3f:ab:cd:0c:85: d3:ac:ca:29:10:74:09:2f:3d:fb:4d:75:3e:32:21:5a:0f:41:
36:45:58:8b:59:28:81:d9:b0:6b:10:4a:d0:7d:59:ad:cf:53: 5f:cc:e7:98:f8:ea:8e:e2:c9:57:60:b6:a3:b0:70:10:18:b9:
05:cb:13:c7:c1:ec:65:64:6b:4d:e6:87:0b:ae:06:60:ab:8a: 86:a3:65:1e:3a:88:13:df:44:18:15:51:00:f6:33:d6:ab:90:
3c:ae:c1:7d:ed:8f:ee:09:02:7a:3a:f2:21:bf:89:ef:cd:14: 18:93:df:ac:7d:15:5c:6a:63:55:d1:4d:41:37:03:89:86:65:
b1:03:64:2d:b2:b6:45:15:da:2d:ee:2d:c0:15:3b:a8:01:a8: fa:fb:d7:b1:73:db:c3:43:08:ff:89:94:89:b1:b4:ad:96:78:
4f:30:61:ae:99:b9:16:07:b5:8b:71:8f:38:ac:69:82:39:90: 52:92:50:8c:0a:5d:ca:29:8b:e0:bc:ca:88:c0:7a:52:48:d3:
92:ff:d6:41:33:3b:92:5b:f2:dd:56:5a:8f:82:d1:1f:76:ee: cf:09:03:08:5f:a1:b9:16:b0:55:5e:11:60:7f:73:9a:98:05:
ca:01:a2:ac:c0:22:41:dd:6e:e1:ce:06:b0:6f:bc:e2:da:91: 54:97:bf:eb:0e:04:61:4f:b4:40:23:61:9a:07:69:78:fc:16:
11:c1:a0:41:16:7d:ba:7e:a1:53:13:14:4b:54:3b:b9:44:cf: de:f4:54:04:cf:f0:2b:07:8d:51:9e:6b:b5:77:c4:13:2c:a3:
4f:1c:ef:ce:a8:bd:e8:ab:ba:de:97:f7:b7:7d:4f:ab:7a:e7: 40:99:ed:fa:f4:00:4a:45:36:da:52:9d:dc:88:66:3e:03:f0:
73:65:97:a1:d9:a3:f3:92:f1:95:06:6d:52:7b:6e:fd:26:56: 20:ce:54:a4:56:58:a8:9e:30:78:e8:42:2d:a8:0f:9b:c4:a9:
55:83:c7:71:f7:a4:8f:9a:2c:52:04:dd:9f:85:ab:9c:88:e1: ab:13:c2:4e:ec:be:2e:99:16:56:2f:22:86:96:27:1d:30:80:
30:c6:4a:88:7d:20:1b:c6:47:8b:82:cc:9d:0f:51:69:b1:90: 7d:a5:f8:45:ef:93:b4:63:13:96:4f:6a:df:a0:11:3b:52:be:
b2:8a:9c:74 93:03:7a:81
-----BEGIN X509 CRL----- -----BEGIN X509 CRL-----
MIICDjCB9wIBATANBgkqhkiG9w0BAQsFADCBnjELMAkGA1UEBhMCVVMxEDAOBgNV MIICDjCB9wIBATANBgkqhkiG9w0BAQsFADCBnjELMAkGA1UEBhMCVVMxEDAOBgNV
BAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xFTATBgNVBAoMDHdvbGZTU0xf BAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xFTATBgNVBAoMDHdvbGZTU0xf
MjA0ODEZMBcGA1UECwwQUHJvZ3JhbW1pbmctMjA0ODEYMBYGA1UEAwwPd3d3Lndv MjA0ODEZMBcGA1UECwwQUHJvZ3JhbW1pbmctMjA0ODEYMBYGA1UEAwwPd3d3Lndv
bGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tFw0yMzEy bGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tFw0yNDAx
MTMyMjE5MzNaFw0yNjA5MDgyMjE5MzNaMBQwEgIBAhcNMjMxMjEzMjIxOTMzWqAO MDkwMDM0MzBaFw0yNjEwMDUwMDM0MzBaMBQwEgIBAhcNMjQwMTA5MDAzNDMwWqAO
MAwwCgYDVR0UBAMCAQgwDQYJKoZIhvcNAQELBQADggEBAHQXm0CB0qDzJmhEW/ii MAwwCgYDVR0UBAMCAQgwDQYJKoZIhvcNAQELBQADggEBAFIRl1cE1+IUH8R/otjP
bD9+cXWif8bmccv5CFdCzT4/q80MhTZFWItZKIHZsGsQStB9Wa3PUwXLE8fB7GVk TLdbDNOsyikQdAkvPftNdT4yIVoPQV/M55j46o7iyVdgtqOwcBAYuYajZR46iBPf
a03mhwuuBmCrijyuwX3tj+4JAno68iG/ie/NFLEDZC2ytkUV2i3uLcAVO6gBqE8w RBgVUQD2M9arkBiT36x9FVxqY1XRTUE3A4mGZfr717Fz28NDCP+JlImxtK2WeFKS
Ya6ZuRYHtYtxjzisaYI5kJL/1kEzO5Jb8t1WWo+C0R927soBoqzAIkHdbuHOBrBv UIwKXcopi+C8yojAelJI088JAwhfobkWsFVeEWB/c5qYBVSXv+sOBGFPtEAjYZoH
vOLakRHBoEEWfbp+oVMTFEtUO7lEz08c786oveirut6X97d9T6t653Nll6HZo/OS aXj8Ft70VATP8CsHjVGea7V3xBMso0CZ7fr0AEpFNtpSndyIZj4D8CDOVKRWWKie
8ZUGbVJ7bv0mVlWDx3H3pI+aLFIE3Z+Fq5yI4TDGSoh9IBvGR4uCzJ0PUWmxkLKK MHjoQi2oD5vEqasTwk7svi6ZFlYvIoaWJx0wgH2l+EXvk7RjE5ZPat+gETtSvpMD
nHQ= eoE=
-----END X509 CRL----- -----END X509 CRL-----

Binary file not shown.

View File

@ -2,40 +2,40 @@ Certificate Revocation List (CRL):
Version 2 (0x1) Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com Issuer: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Last Update: Dec 13 22:19:33 2023 GMT Last Update: Jan 9 00:34:30 2024 GMT
Next Update: Sep 8 22:19:33 2026 GMT Next Update: Oct 5 00:34:30 2026 GMT
CRL extensions: CRL extensions:
X509v3 CRL Number: X509v3 CRL Number:
2 2
Revoked Certificates: Revoked Certificates:
Serial Number: 02 Serial Number: 02
Revocation Date: Dec 13 22:19:33 2023 GMT Revocation Date: Jan 9 00:34:30 2024 GMT
Signature Algorithm: sha256WithRSAEncryption Signature Algorithm: sha256WithRSAEncryption
48:36:98:18:42:9c:0c:81:51:19:75:4b:26:9a:e0:07:18:89: b3:6f:ed:72:d2:73:6a:77:bf:3a:55:bc:54:18:6a:71:bc:6a:
a2:a1:bd:b6:4e:91:f2:44:93:1a:50:a1:8f:72:1f:c4:ae:99: cc:cd:5d:90:f5:64:8d:1b:f0:e0:48:7b:f2:7b:06:86:53:63:
81:c5:00:3a:94:03:de:00:24:98:d4:2c:17:e5:ba:f2:29:3a: 9b:d8:24:15:10:b1:19:96:9b:d2:75:a8:25:a2:35:a9:14:d6:
43:c8:23:ba:73:6a:5c:99:5d:ba:80:dd:bd:4f:cd:53:a6:cf: d5:5e:53:e3:34:9d:f2:8b:07:19:9b:1f:f1:02:0f:04:46:e8:
33:11:31:30:27:e2:d2:31:06:65:b8:3e:cf:fe:00:21:ff:0d: b8:b6:f2:8d:c7:c0:15:3e:3e:8e:96:73:15:1e:62:f6:4e:2a:
18:4f:fc:fd:d5:80:75:72:7c:2e:44:c1:a1:26:a6:8a:88:c8: f7:aa:a0:91:80:12:7f:81:0c:65:cc:38:be:58:6c:14:a5:21:
c0:66:1a:d4:99:36:ca:8f:67:42:8f:7c:f2:1a:e7:1b:d0:90: a1:8d:f7:8a:b9:24:f4:2d:ca:c0:67:43:0b:c8:1c:b4:7d:12:
05:22:0d:29:d3:35:57:23:8c:bb:d2:53:c1:a8:00:3c:d4:b3: 7f:a2:1b:19:0e:94:cf:7b:9f:75:a0:08:9a:67:3f:87:89:3e:
97:23:8a:4f:1d:8b:c9:73:6a:96:40:b0:a4:b1:c7:de:06:4d: f8:58:a5:8a:1b:2d:da:9b:d0:1b:18:92:c3:d2:6a:d7:1c:fc:
a3:5d:6a:d2:f5:5c:1e:f0:21:0f:d1:fd:21:89:e2:9e:3d:c1: 45:69:77:c3:57:65:75:99:9e:47:2a:20:25:ef:90:f2:5f:3b:
b2:f0:0f:5e:79:1e:47:48:92:bf:eb:96:28:ad:0b:89:5e:3b: 7d:9c:7d:00:ea:92:54:eb:0b:e7:17:af:24:1a:f9:7c:83:50:
ed:97:29:bb:8d:24:c2:e6:26:e5:33:ef:88:17:c1:1a:97:fa: 68:1d:dc:5b:60:12:a7:52:78:d9:a9:b0:1f:59:48:36:c7:a6:
51:44:a2:cc:b2:64:e5:5c:94:54:ed:3b:7d:8f:34:4a:4b:d3: 97:34:c7:87:3f:ae:fd:a9:56:5d:48:cc:89:7a:79:60:8f:9b:
ca:62:f9:20:00:86:26:ea:1b:a9:b4:df:8f:f4:4d:d8:3e:95: 2b:63:3c:b3:04:1d:5f:f7:20:d2:fd:f2:51:b1:96:93:13:5b:
aa:3b:43:1c ab:74:82:8b
-----BEGIN X509 CRL----- -----BEGIN X509 CRL-----
MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADCBlDELMAkGA1UEBhMCVVMxEDAOBgNV MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADCBlDELMAkGA1UEBhMCVVMxEDAOBgNV
BAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNhd3Rvb3Ro BAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNhd3Rvb3Ro
MRMwEQYDVQQLDApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20x MRMwEQYDVQQLDApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20x
HzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20XDTIzMTIxMzIyMTkzM1oX HzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20XDTI0MDEwOTAwMzQzMFoX
DTI2MDkwODIyMTkzM1owFDASAgECFw0yMzEyMTMyMjE5MzNaoA4wDDAKBgNVHRQE DTI2MTAwNTAwMzQzMFowFDASAgECFw0yNDAxMDkwMDM0MzBaoA4wDDAKBgNVHRQE
AwIBAjANBgkqhkiG9w0BAQsFAAOCAQEASDaYGEKcDIFRGXVLJprgBxiJoqG9tk6R AwIBAjANBgkqhkiG9w0BAQsFAAOCAQEAs2/tctJzane/OlW8VBhqcbxqzM1dkPVk
8kSTGlChj3IfxK6ZgcUAOpQD3gAkmNQsF+W68ik6Q8gjunNqXJlduoDdvU/NU6bP jRvw4Eh78nsGhlNjm9gkFRCxGZab0nWoJaI1qRTW1V5T4zSd8osHGZsf8QIPBEbo
MxExMCfi0jEGZbg+z/4AIf8NGE/8/dWAdXJ8LkTBoSamiojIwGYa1Jk2yo9nQo98 uLbyjcfAFT4+jpZzFR5i9k4q96qgkYASf4EMZcw4vlhsFKUhoY33irkk9C3KwGdD
8hrnG9CQBSINKdM1VyOMu9JTwagAPNSzlyOKTx2LyXNqlkCwpLHH3gZNo11q0vVc C8gctH0Sf6IbGQ6Uz3ufdaAImmc/h4k++Filihst2pvQGxiSw9Jq1xz8RWl3w1dl
HvAhD9H9IYninj3BsvAPXnkeR0iSv+uWKK0LiV477Zcpu40kwuYm5TPviBfBGpf6 dZmeRyogJe+Q8l87fZx9AOqSVOsL5xevJBr5fINQaB3cW2ASp1J42amwH1lINsem
UUSizLJk5VyUVO07fY80SkvTymL5IACGJuobqbTfj/RN2D6VqjtDHA== lzTHhz+u/alWXUjMiXp5YI+bK2M8swQdX/cg0v3yUbGWkxNbq3SCiw==
-----END X509 CRL----- -----END X509 CRL-----

View File

@ -2,43 +2,43 @@ Certificate Revocation List (CRL):
Version 2 (0x1) Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com Issuer: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Last Update: Dec 13 22:19:33 2023 GMT Last Update: Jan 9 00:34:30 2024 GMT
Next Update: Sep 8 22:19:33 2026 GMT Next Update: Oct 5 00:34:30 2026 GMT
CRL extensions: CRL extensions:
X509v3 CRL Number: X509v3 CRL Number:
3 3
Revoked Certificates: Revoked Certificates:
Serial Number: 01 Serial Number: 01
Revocation Date: Dec 13 22:19:33 2023 GMT Revocation Date: Jan 9 00:34:30 2024 GMT
Serial Number: 02 Serial Number: 02
Revocation Date: Dec 13 22:19:33 2023 GMT Revocation Date: Jan 9 00:34:30 2024 GMT
Signature Algorithm: sha256WithRSAEncryption Signature Algorithm: sha256WithRSAEncryption
72:6e:a4:64:36:6b:e8:e0:c5:1d:98:ef:ab:7e:7a:14:f2:8d: 35:50:96:da:71:71:90:d5:b7:37:5a:a6:b9:09:07:2f:af:c9:
99:d0:57:4b:76:ac:f4:89:60:cd:89:23:9d:01:34:f3:83:e5: e0:02:32:6a:43:6e:20:ec:20:a4:ac:d0:39:a9:19:35:d0:d2:
82:21:b3:48:c4:42:25:7f:ea:9f:74:5f:e8:b8:d6:71:bb:a2: 6f:bb:d1:cd:46:10:a7:cb:8a:be:0a:02:a2:91:f5:29:74:ee:
39:d8:ef:46:a8:13:ba:7d:44:ab:d6:13:65:18:de:b5:03:85: 34:83:a3:8c:a0:ca:39:af:94:4a:23:d7:56:57:6b:cc:c6:eb:
a7:c6:4f:0a:a0:6a:78:ba:7b:f7:ce:6e:ba:1c:ef:6f:b1:04: b0:ce:9f:0a:e1:b0:a8:12:6b:6a:8b:21:73:22:6f:49:41:cd:
a8:ac:c6:de:3b:76:77:3e:3d:8b:ae:8b:2b:7e:c9:4f:77:31: fd:85:44:d1:fa:52:6b:2f:b2:2b:02:e7:43:0e:f1:92:bc:15:
7f:1f:f5:04:2c:e9:cf:a1:56:c2:59:e9:be:49:9f:e8:67:a3: 8f:22:28:49:25:69:93:d8:50:10:2f:93:e2:f5:b0:31:5c:eb:
42:66:05:21:02:64:82:b2:74:a7:4b:89:89:7d:43:1a:41:fd: 1a:35:e2:40:83:25:87:55:4d:c0:85:06:37:9e:23:44:80:a1:
53:8c:d6:4f:27:04:2a:48:6b:9e:62:fa:4a:42:83:22:53:3f: f9:e2:eb:9c:90:28:7a:71:d8:55:a2:8b:70:32:31:33:26:70:
53:07:4f:bc:cd:8d:8d:cc:15:c6:ff:3c:af:7d:db:ab:dd:fa: fe:1d:11:d5:4b:c1:04:47:19:59:44:8f:0b:0a:ec:d6:62:40:
8f:65:86:86:2a:89:5e:3f:d5:4b:39:80:78:3f:6e:38:3b:6d: 8a:6f:67:2e:6a:50:38:54:35:c9:f8:d5:ec:e8:ae:93:88:3d:
a5:5e:2c:9e:1d:2f:9c:62:12:b1:34:f2:95:64:37:dc:4b:20: a0:40:81:2c:e0:fe:f7:c8:68:24:8e:41:04:88:af:94:82:97:
dc:27:f3:de:81:67:b2:04:b0:14:b9:47:e3:65:e3:2f:35:27: 75:e5:69:4c:22:1d:f9:67:53:a3:4c:a3:db:bf:55:08:e7:3a:
c2:fc:22:db:24:bd:04:58:88:17:e3:42:3c:a5:ef:53:39:15: 07:67:a2:28:25:63:af:f8:0e:c7:d3:c1:77:ef:20:20:20:63:
54:52:ac:a1 9e:5c:22:81
-----BEGIN X509 CRL----- -----BEGIN X509 CRL-----
MIICGTCCAQECAQEwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVTMRAwDgYD MIICGTCCAQECAQEwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVTMRAwDgYD
VQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMREwDwYDVQQKDAhTYXd0b290 VQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMREwDwYDVQQKDAhTYXd0b290
aDETMBEGA1UECwwKQ29uc3VsdGluZzEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29t aDETMBEGA1UECwwKQ29uc3VsdGluZzEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29t
MR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tFw0yMzEyMTMyMjE5MzNa MR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tFw0yNDAxMDkwMDM0MzBa
Fw0yNjA5MDgyMjE5MzNaMCgwEgIBARcNMjMxMjEzMjIxOTMzWjASAgECFw0yMzEy Fw0yNjEwMDUwMDM0MzBaMCgwEgIBARcNMjQwMTA5MDAzNDMwWjASAgECFw0yNDAx
MTMyMjE5MzNaoA4wDDAKBgNVHRQEAwIBAzANBgkqhkiG9w0BAQsFAAOCAQEAcm6k MDkwMDM0MzBaoA4wDDAKBgNVHRQEAwIBAzANBgkqhkiG9w0BAQsFAAOCAQEANVCW
ZDZr6ODFHZjvq356FPKNmdBXS3as9IlgzYkjnQE084PlgiGzSMRCJX/qn3Rf6LjW 2nFxkNW3N1qmuQkHL6/J4AIyakNuIOwgpKzQOakZNdDSb7vRzUYQp8uKvgoCopH1
cbuiOdjvRqgTun1Eq9YTZRjetQOFp8ZPCqBqeLp7985uuhzvb7EEqKzG3jt2dz49 KXTuNIOjjKDKOa+USiPXVldrzMbrsM6fCuGwqBJraoshcyJvSUHN/YVE0fpSay+y
i66LK37JT3cxfx/1BCzpz6FWwlnpvkmf6GejQmYFIQJkgrJ0p0uJiX1DGkH9U4zW KwLnQw7xkrwVjyIoSSVpk9hQEC+T4vWwMVzrGjXiQIMlh1VNwIUGN54jRICh+eLr
TycEKkhrnmL6SkKDIlM/UwdPvM2NjcwVxv88r33bq936j2WGhiqJXj/VSzmAeD9u nJAoenHYVaKLcDIxMyZw/h0R1UvBBEcZWUSPCwrs1mJAim9nLmpQOFQ1yfjV7Oiu
ODttpV4snh0vnGISsTTylWQ33Esg3Cfz3oFnsgSwFLlH42XjLzUnwvwi2yS9BFiI k4g9oECBLOD+98hoJI5BBIivlIKXdeVpTCId+WdTo0yj279VCOc6B2eiKCVjr/gO
F+NCPKXvUzkVVFKsoQ== x9PBd+8gICBjnlwigQ==
-----END X509 CRL----- -----END X509 CRL-----

View File

@ -2,25 +2,25 @@ Certificate Revocation List (CRL):
Version 2 (0x1) Version 2 (0x1)
Signature Algorithm: ecdsa-with-SHA256 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 Issuer: C = US, ST = Oregon, L = Salem, O = Client ECC, OU = Fast, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Last Update: Dec 13 22:19:33 2023 GMT Last Update: Jan 9 00:34:30 2024 GMT
Next Update: Sep 8 22:19:33 2026 GMT Next Update: Oct 5 00:34:30 2026 GMT
CRL extensions: CRL extensions:
X509v3 CRL Number: X509v3 CRL Number:
9 9
Revoked Certificates: Revoked Certificates:
Serial Number: 02 Serial Number: 02
Revocation Date: Dec 13 22:19:33 2023 GMT Revocation Date: Jan 9 00:34:30 2024 GMT
Signature Algorithm: ecdsa-with-SHA256 Signature Algorithm: ecdsa-with-SHA256
30:45:02:21:00:dc:a7:bf:34:1b:68:b6:54:0c:38:8d:46:41: 30:45:02:20:3b:07:f1:6c:fb:19:62:f2:56:2a:5c:21:a3:7d:
84:bf:fa:f0:96:00:89:a6:81:4a:0f:15:12:ef:15:98:f7:51: bf:06:33:3e:b4:53:01:f3:f5:0e:e6:ca:f5:b9:26:7e:4d:ca:
95:02:20:08:57:33:0d:c1:a5:c6:83:63:49:96:8c:71:41:7b: 02:21:00:dd:04:d6:b1:18:01:b7:d6:ca:d9:7b:29:53:cf:9e:
40:92:67:80:d6:23:62:2a:c2:f2:43:5a:92:9b:9b:d6:83 ad:38:ef:fa:70:2c:41:74:ba:ce:e6:77:1f:22:86:f0:e3
-----BEGIN X509 CRL----- -----BEGIN X509 CRL-----
MIIBPDCB4wIBATAKBggqhkjOPQQDAjCBjTELMAkGA1UEBhMCVVMxDzANBgNVBAgM MIIBPDCB4wIBATAKBggqhkjOPQQDAjCBjTELMAkGA1UEBhMCVVMxDzANBgNVBAgM
Bk9yZWdvbjEOMAwGA1UEBwwFU2FsZW0xEzARBgNVBAoMCkNsaWVudCBFQ0MxDTAL Bk9yZWdvbjEOMAwGA1UEBwwFU2FsZW0xEzARBgNVBAoMCkNsaWVudCBFQ0MxDTAL
BgNVBAsMBEZhc3QxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3 BgNVBAsMBEZhc3QxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqGSIb3
DQEJARYQaW5mb0B3b2xmc3NsLmNvbRcNMjMxMjEzMjIxOTMzWhcNMjYwOTA4MjIx DQEJARYQaW5mb0B3b2xmc3NsLmNvbRcNMjQwMTA5MDAzNDMwWhcNMjYxMDA1MDAz
OTMzWjAUMBICAQIXDTIzMTIxMzIyMTkzM1qgDjAMMAoGA1UdFAQDAgEJMAoGCCqG NDMwWjAUMBICAQIXDTI0MDEwOTAwMzQzMFqgDjAMMAoGA1UdFAQDAgEJMAoGCCqG
SM49BAMCA0gAMEUCIQDcp780G2i2VAw4jUZBhL/68JYAiaaBSg8VEu8VmPdRlQIg SM49BAMCA0gAMEUCIDsH8Wz7GWLyVipcIaN9vwYzPrRTAfP1DubK9bkmfk3KAiEA
CFczDcGlxoNjSZaMcUF7QJJngNYjYirC8kNakpub1oM= 3QTWsRgBt9bK2XspU8+erTjv+nAsQXS6zuZ3HyKG8OM=
-----END X509 CRL----- -----END X509 CRL-----

View File

@ -2,25 +2,25 @@ Certificate Revocation List (CRL):
Version 2 (0x1) Version 2 (0x1)
Signature Algorithm: ecdsa-with-SHA256 Signature Algorithm: ecdsa-with-SHA256
Issuer: C = US, ST = Washington, L = Seattle, O = Elliptic, OU = ECC, CN = www.wolfssl.com, emailAddress = info@wolfssl.com Issuer: C = US, ST = Washington, L = Seattle, O = Elliptic, OU = ECC, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Last Update: Dec 13 22:19:33 2023 GMT Last Update: Jan 9 00:34:30 2024 GMT
Next Update: Sep 8 22:19:33 2026 GMT Next Update: Oct 5 00:34:30 2026 GMT
CRL extensions: CRL extensions:
X509v3 CRL Number: X509v3 CRL Number:
10 10
Revoked Certificates: Revoked Certificates:
Serial Number: 02 Serial Number: 02
Revocation Date: Dec 13 22:19:33 2023 GMT Revocation Date: Jan 9 00:34:30 2024 GMT
Signature Algorithm: ecdsa-with-SHA256 Signature Algorithm: ecdsa-with-SHA256
30:45:02:21:00:a9:26:ab:1a:4a:be:5c:92:da:9d:17:0a:b5: 30:45:02:20:4e:83:3e:21:ee:69:a6:f2:7e:87:45:10:5c:60:
f6:40:ea:84:93:ce:57:b8:af:68:75:e8:e9:de:a7:27:e7:79: ad:24:49:1e:0f:9e:1f:81:03:00:43:a9:e6:1b:63:27:3f:6b:
48:02:20:11:d4:03:97:19:2a:28:04:70:28:bb:5e:6a:b7:f6: 02:21:00:b2:7f:bd:3d:af:c4:f5:ff:82:3f:b7:6a:56:25:7c:
32:90:f1:92:ff:48:7c:cf:e7:94:0f:ce:63:de:f8:fc:6c 07:85:54:d9:19:44:42:60:b4:8a:e3:55:f4:a4:96:c7:d1
-----BEGIN X509 CRL----- -----BEGIN X509 CRL-----
MIIBPzCB5gIBATAKBggqhkjOPQQDAjCBkDELMAkGA1UEBhMCVVMxEzARBgNVBAgM MIIBPzCB5gIBATAKBggqhkjOPQQDAjCBkDELMAkGA1UEBhMCVVMxEzARBgNVBAgM
Cldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxETAPBgNVBAoMCEVsbGlwdGlj Cldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxETAPBgNVBAoMCEVsbGlwdGlj
MQwwCgYDVQQLDANFQ0MxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG MQwwCgYDVQQLDANFQ0MxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG
SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbRcNMjMxMjEzMjIxOTMzWhcNMjYwOTA4 SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbRcNMjQwMTA5MDAzNDMwWhcNMjYxMDA1
MjIxOTMzWjAUMBICAQIXDTIzMTIxMzIyMTkzM1qgDjAMMAoGA1UdFAQDAgEKMAoG MDAzNDMwWjAUMBICAQIXDTI0MDEwOTAwMzQzMFqgDjAMMAoGA1UdFAQDAgEKMAoG
CCqGSM49BAMCA0gAMEUCIQCpJqsaSr5cktqdFwq19kDqhJPOV7ivaHXo6d6nJ+d5 CCqGSM49BAMCA0gAMEUCIE6DPiHuaabyfodFEFxgrSRJHg+eH4EDAEOp5htjJz9r
SAIgEdQDlxkqKARwKLtearf2MpDxkv9IfM/nlA/OY974/Gw= AiEAsn+9Pa/E9f+CP7dqViV8B4VU2RlEQmC0iuNV9KSWx9E=
-----END X509 CRL----- -----END X509 CRL-----

Binary file not shown.

View File

@ -0,0 +1,36 @@
# Script to print out WKS keystores using keytool -list
#
# Primarily used as a sanity check that keytool can successfully process
# WKS KeyStore files using the -list command
#
# Export library paths for Linux and Mac to find shared JNI library
export LD_LIBRARY_PATH=../../lib:$LD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=../../lib:$DYLD_LIBRARY_PATH
# ARGS: <keystore file> <password>
print_wks() {
printf "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
printf "KEYSTORE: $1\n"
keytool -list -provider com.wolfssl.provider.jce.WolfCryptProvider --providerpath ../../lib/wolfcrypt-jni.jar -storetype WKS -storepass "$2" -keystore ${1}
if [ $? -ne 0 ]; then
printf "fail"
exit 1
fi
}
print_wks "client.wks" "wolfSSL test"
print_wks "client-rsa-1024.wks" "wolfSSL test"
print_wks "client-rsa.wks" "wolfSSL test"
print_wks "client-ecc.wks" "wolfSSL test"
print_wks "server.wks" "wolfSSL test"
print_wks "server-rsa-1024.wks" "wolfSSL test"
print_wks "server-rsa.wks" "wolfSSL test"
print_wks "server-ecc.wks" "wolfSSL test"
print_wks "cacerts.wks" "wolfSSL test"
print_wks "ca-client.wks" "wolfSSL test"
print_wks "ca-server.wks" "wolfSSL test"
print_wks "ca-server-rsa-2048.wks" "wolfSSL test"
print_wks "ca-server-ecc-256.wks" "wolfSSL test"
printf "\nSUCCESS printing all KeyStore files\n"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,133 @@
#!/bin/sh
#
# Script to convert system CA certs KeyStore file from JKS to WKS format
#
# This script tries to detect OS variant and Java version to find correct
# CA certificate KeyStore for this system.
#
# The following search order is used for trying to find either cacerts,
# jssecacerts, or both:
#
# cacerts
# 1. $JAVA_HOME/lib/security/cacerts (JDK 9+)
# 2. $JAVA_HOME/jre/lib/security/cacerts (JDK <= 8)
#
# jssecacerts:
#
# 1. $JAVA_HOME/lib/security/jssecacerts (JDK 9+)
# 2. $JAVA_HOME/jre/lib/security/jssecacerts (JDK <= 8)
#
# Export library paths for Linux and Mac to find shared JNI library
export LD_LIBRARY_PATH=../../../lib:$LD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=../../../lib:$DYLD_LIBRARY_PATH
OUTDIR=`pwd`
# ARGS: <input-keystore-name> <output-keystore-name> <password>
jks_to_wks() {
keytool -importkeystore -srckeystore ${1} -destkeystore ${2}.wks -srcstoretype JKS -deststoretype WKS -srcstorepass "$3" -deststorepass "$3" -provider com.wolfssl.provider.jce.WolfCryptProvider --providerpath ../../../lib/wolfcrypt-jni.jar &> /dev/null
if [ $? -ne 0 ]; then
printf "Failed to convert JKS to WKS!"
exit 1
fi
}
OS=`uname`
ARCH=`uname -a`
CACERTS_JDK9="lib/security/cacerts"
CACERTS_JDK8="jre/lib/security/cacerts"
JSSECACERTS_JDK9="lib/security/jssecacerts"
JSSECACERTS_JDK8="jre/lib/security/jssecacerts"
echo "-----------------------------------------------------------------------"
echo "System CA KeyStore to WKS Conversion Script"
echo "-----------------------------------------------------------------------"
if [ -z "$JAVA_HOME" ]; then
echo "JAVA_HOME empty, trying to detect"
else
echo "JAVA_HOME already set = $JAVA_HOME"
javaHome="$JAVA_HOME"
fi
# Set up Java include and library paths for OS X and Linux
# NOTE: you may need to modify these if your platform uses different locations
if [ "$OS" == "Darwin" ]; then
echo "Detected Darwin/OSX host OS"
if [ -z $javaHome ]; then
# this is broken since Big Sur, set JAVA_HOME environment var instead
# OSX JAVA_HOME is typically similar to:
# /Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home
javaHome=`/usr/libexec/java_home`
fi
elif [ "$OS" == "Linux" ] ; then
echo "Detected Linux host OS"
if [ -z $javaHome ]; then
javaHome=`echo $(dirname $(dirname $(readlink -f $(which java))))`
fi
if [ ! -d "$javaHome/include" ]
then
javaHome=`echo $(dirname $javaHome)`
fi
else
echo 'Unknown host OS!'
exit
fi
echo " $OS $ARCH"
echo "Java Home = $javaHome"
echo ""
if [ ! -d $OUTDIR ]; then
mkdir $OUTDIR
fi
if [ -f "$javaHome/$CACERTS_JDK9" ]; then
echo "System cacerts found, converting from JKS to WKS:"
echo " FROM: $javaHome/$CACERTS_JDK9"
echo " TO: $OUTDIR/cacerts.wks"
echo " PASS (default): changeit"
if [ -f $OUTDIR/cacerts.wks ]; then
rm $OUTDIR/cacerts.wks
fi
jks_to_wks "$javaHome/$CACERTS_JDK9" "$OUTDIR/cacerts" "changeit"
fi
if [ -f "$javaHome/$CACERTS_JDK8" ]; then
echo "System cacerts found, converting from JKS to WKS:"
echo " FROM: $javaHome/$CACERTS_JDK8"
echo " TO: $OUTDIR/cacerts.wks"
echo " PASS (default): changeit"
if [ -f $OUTDIR/cacerts.wks ]; then
rm $OUTDIR/cacerts.wks
fi
jks_to_wks "$javaHome/$CACERTS_JDK8" "$OUTDIR/cacerts" "changeit"
fi
if [ -f "$javaHome/$JSSECERTS_JDK9" ]; then
echo "System jssecacerts found, converting from JKS to WKS:"
echo " FROM: $javaHome/$JSSECACERTS_JDK9"
echo " TO: $OUTDIR/jssecacerts.wks"
echo " PASS (default): changeit"
if [ -f $OUTDIR/jssecacerts.wks ]; then
rm $OUTDIR/jssecacerts.wks
fi
jks_to_wks "$javaHome/$JSSECACERTS_JDK9" "$OUTDIR/jssecacerts" "changeit"
fi
if [ -f "$javaHome/$JSSECERTS_JDK8" ]; then
echo "System jssecacerts found, converting from JKS to WKS:"
echo " FROM: $javaHome/$JSSECACERTS_JDK8"
echo " TO: $OUTDIR/jssecacerts.wks"
echo " PASS (default): changeit"
if [ -f $OUTDIR/jssecacerts.wks ]; then
rm $OUTDIR/jssecacerts.wks
fi
jks_to_wks "$javaHome/$JSSECACERTS_JDK8" "$OUTDIR/jssecacerts" "changeit"
fi
echo ""
echo "Successfully converted JKS to WKS"

View File

@ -44,11 +44,14 @@ certList=(
"ecc-client-key.der" "ecc-client-key.der"
"ecc-client-key.pem" "ecc-client-key.pem"
"ecc-key.pem" "ecc-key.pem"
"ecc-keyPkcs8.der"
"server-cert.pem" "server-cert.pem"
"server-cert.der" "server-cert.der"
"server-ecc.pem" "server-ecc.pem"
"server-ecc.der" "server-ecc.der"
"server-key.pem" "server-key.pem"
"server-key.der"
"server-keyPkcs8.der"
"crl/cliCrl.pem" "crl/cliCrl.pem"
"crl/crl.pem" "crl/crl.pem"
"crl/crl.der" "crl/crl.der"

View File

@ -45,7 +45,11 @@ if [ -z "$1" ]; then
fi fi
CERT_LOCATION=$1 CERT_LOCATION=$1
# keystore-name , cert file , alias , password # Export library paths for Linux and Mac to find shared JNI library
export LD_LIBRARY_PATH=../../lib:$LD_LIBRARY_PATH
export DYLD_LIBRARY_PATH=../../lib:$DYLD_LIBRARY_PATH
# ARGS: <keystore-name> <cert file> <alias> <password>
add_cert() { add_cert() {
keytool -import -keystore "$1" -file "$CERT_LOCATION/$2" -alias "$3" -noprompt -trustcacerts -deststoretype JKS -storepass "$4" &> /dev/null keytool -import -keystore "$1" -file "$CERT_LOCATION/$2" -alias "$3" -noprompt -trustcacerts -deststoretype JKS -storepass "$4" &> /dev/null
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
@ -54,7 +58,7 @@ add_cert() {
fi fi
} }
# keystore-name , cert file , key file , alias , password # ARGS: <keystore-name> <cert file> <key file> <alias> <password>
add_cert_key() { add_cert_key() {
openssl pkcs12 -export -in "$CERT_LOCATION/$2" -inkey "$CERT_LOCATION/$3" -out tmp.p12 -passin pass:"$5" -passout pass:"$5" -name "$4" &> /dev/null openssl pkcs12 -export -in "$CERT_LOCATION/$2" -inkey "$CERT_LOCATION/$3" -out tmp.p12 -passin pass:"$5" -passout pass:"$5" -name "$4" &> /dev/null
keytool -importkeystore -deststorepass "$5" -destkeystore "$1" -deststoretype JKS -srckeystore tmp.p12 -srcstoretype PKCS12 -srcstorepass "$5" -alias "$4" &> /dev/null keytool -importkeystore -deststorepass "$5" -destkeystore "$1" -deststoretype JKS -srckeystore tmp.p12 -srcstoretype PKCS12 -srcstorepass "$5" -alias "$4" &> /dev/null
@ -65,6 +69,16 @@ add_cert_key() {
rm tmp.p12 rm tmp.p12
} }
# ARGS: <keystore-name> <password>
jks_to_wks() {
keytool -importkeystore -srckeystore ${1}.jks -destkeystore ${1}.wks -srcstoretype JKS -deststoretype WKS -srcstorepass "$2" -deststorepass "$2" -provider com.wolfssl.provider.jce.WolfCryptProvider --providerpath ../../lib/wolfcrypt-jni.jar &> /dev/null
if [ $? -ne 0 ]; then
printf "fail"
exit 1
fi
}
#################### CLIENT KEYSTORES #################### #################### CLIENT KEYSTORES ####################
# Client cert: both RSA 2048-bit and ECC # Client cert: both RSA 2048-bit and ECC
@ -166,3 +180,72 @@ rm ca-server-ecc-256.jks &> /dev/null
add_cert "ca-server-ecc-256.jks" "/ca-ecc-cert.pem" "ca-ecc" "wolfSSL test" add_cert "ca-server-ecc-256.jks" "/ca-ecc-cert.pem" "ca-ecc" "wolfSSL test"
printf "done\n" printf "done\n"
################### CONVERT JKS TO WKS ###################
printf "\nConverting keystores from JKS to WKS ...\n"
printf "\tCreating client.wks ..."
rm client.wks &> /dev/null
jks_to_wks "client" "wolfSSL test"
printf "done\n"
printf "\tCreating client-rsa-1024.wks ..."
rm client-rsa-1024.wks &> /dev/null
jks_to_wks "client-rsa-1024" "wolfSSL test"
printf "done\n"
printf "\tCreating client-rsa.wks ..."
rm client-rsa.wks &> /dev/null
jks_to_wks "client-rsa" "wolfSSL test"
printf "done\n"
printf "\tCreating client-ecc.wks ..."
rm client-ecc.wks &> /dev/null
jks_to_wks "client-ecc" "wolfSSL test"
printf "done\n"
printf "\tCreating server.wks ..."
rm server.wks &> /dev/null
jks_to_wks "server" "wolfSSL test"
printf "done\n"
printf "\tCreating server-rsa-1024.wks ..."
rm server-rsa-1024.wks &> /dev/null
jks_to_wks "server-rsa-1024" "wolfSSL test"
printf "done\n"
printf "\tCreating server-rsa.wks ..."
rm server-rsa.wks &> /dev/null
jks_to_wks "server-rsa" "wolfSSL test"
printf "done\n"
printf "\tCreating server-ecc.wks ..."
rm server-ecc.wks &> /dev/null
jks_to_wks "server-ecc" "wolfSSL test"
printf "done\n"
printf "\tCreating cacerts.wks ..."
rm cacerts.wks &> /dev/null
jks_to_wks "cacerts" "wolfSSL test"
printf "done\n"
printf "\tCreating ca-client.wks ..."
rm ca-client.wks &> /dev/null
jks_to_wks "ca-client" "wolfSSL test"
printf "done\n"
printf "\tCreating ca-server.wks ..."
rm ca-server.wks &> /dev/null
jks_to_wks "ca-server" "wolfSSL test"
printf "done\n"
printf "\tCreating ca-server-rsa-2048.wks ..."
rm ca-server-rsa-2048.wks &> /dev/null
jks_to_wks "ca-server-rsa-2048" "wolfSSL test"
printf "done\n"
printf "\tCreating ca-server-ecc-256.wks ..."
rm ca-server-ecc-256.wks &> /dev/null
jks_to_wks "ca-server-ecc-256" "wolfSSL test"
printf "done\n"

View File

@ -0,0 +1,276 @@
/* WolfSSLKeyStoreExample.java
*
* Copyright (C) 2006-2024 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 = "wolfSSL test";
/* 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();
}
}
}

View File

@ -0,0 +1,6 @@
#!/bin/bash
cd ./examples/build/provider
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../../lib/:/usr/local/lib
java -classpath ../../../lib/wolfcrypt-jni.jar:./ -Dsun.boot.library.path=../../../lib/ -Dwolfjce.debug=true WolfSSLKeyStoreExample $@

View File

@ -0,0 +1,45 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_wolfssl_provider_jce_WolfSSLKeyStore */
#ifndef _Included_com_wolfssl_provider_jce_WolfSSLKeyStore
#define _Included_com_wolfssl_provider_jce_WolfSSLKeyStore
#ifdef __cplusplus
extern "C" {
#endif
#undef com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_PBKDF2_SALT_SIZE
#define com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_PBKDF2_SALT_SIZE 16L
#undef com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_PBKDF2_MIN_ITERATIONS
#define com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_PBKDF2_MIN_ITERATIONS 10000L
#undef com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_PBKDF2_DEFAULT_ITERATIONS
#define com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_PBKDF2_DEFAULT_ITERATIONS 210000L
#undef com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_ENC_IV_LENGTH
#define com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_ENC_IV_LENGTH 16L
#undef com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_ENC_KEY_LENGTH
#define com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_ENC_KEY_LENGTH 32L
#undef com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_HMAC_KEY_LENGTH
#define com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_HMAC_KEY_LENGTH 64L
#undef com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_DEFAULT_MAX_CHAIN_COUNT
#define com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_DEFAULT_MAX_CHAIN_COUNT 100L
#undef com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_MAGIC_NUMBER
#define com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_MAGIC_NUMBER 7L
#undef com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_STORE_VERSION
#define com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_STORE_VERSION 1L
#undef com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_ENTRY_ID_PRIVATE_KEY
#define com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_ENTRY_ID_PRIVATE_KEY 1L
#undef com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_ENTRY_ID_CERTIFICATE
#define com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_ENTRY_ID_CERTIFICATE 2L
#undef com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_ENTRY_ID_SECRET_KEY
#define com_wolfssl_provider_jce_WolfSSLKeyStore_WKS_ENTRY_ID_SECRET_KEY 3L
/*
* Class: com_wolfssl_provider_jce_WolfSSLKeyStore
* Method: X509CheckPrivateKey
* Signature: ([B[B)Z
*/
JNIEXPORT jboolean JNICALL Java_com_wolfssl_provider_jce_WolfSSLKeyStore_X509CheckPrivateKey
(JNIEnv *, jobject, jbyteArray, jbyteArray);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -9,6 +9,16 @@ extern "C" {
#endif #endif
#undef com_wolfssl_wolfcrypt_Asn_MAX_ENCODED_SIG_SIZE #undef com_wolfssl_wolfcrypt_Asn_MAX_ENCODED_SIG_SIZE
#define com_wolfssl_wolfcrypt_Asn_MAX_ENCODED_SIG_SIZE 512L #define com_wolfssl_wolfcrypt_Asn_MAX_ENCODED_SIG_SIZE 512L
#undef com_wolfssl_wolfcrypt_Asn_DSAk
#define com_wolfssl_wolfcrypt_Asn_DSAk 515L
#undef com_wolfssl_wolfcrypt_Asn_RSAk
#define com_wolfssl_wolfcrypt_Asn_RSAk 645L
#undef com_wolfssl_wolfcrypt_Asn_RSAPSSk
#define com_wolfssl_wolfcrypt_Asn_RSAPSSk 654L
#undef com_wolfssl_wolfcrypt_Asn_RSAESOAEPk
#define com_wolfssl_wolfcrypt_Asn_RSAESOAEPk 651L
#undef com_wolfssl_wolfcrypt_Asn_ECDSAk
#define com_wolfssl_wolfcrypt_Asn_ECDSAk 518L
/* /*
* Class: com_wolfssl_wolfcrypt_Asn * Class: com_wolfssl_wolfcrypt_Asn
* Method: encodeSignature * Method: encodeSignature
@ -33,6 +43,14 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_Asn_encodeSignature___3B_3BJI
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Asn_getCTC_1HashOID JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Asn_getCTC_1HashOID
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jint);
/*
* Class: com_wolfssl_wolfcrypt_Asn
* Method: getPkcs8AlgoID
* Signature: ([B)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Asn_getPkcs8AlgoID
(JNIEnv *, jclass, jbyteArray);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -191,6 +191,14 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_138
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_1512Enabled JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_1512Enabled
(JNIEnv *, jclass); (JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_FeatureDetect
* Method: Pbkdf1Enabled
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_Pbkdf1Enabled
(JNIEnv *, jclass);
/* /*
* Class: com_wolfssl_wolfcrypt_FeatureDetect * Class: com_wolfssl_wolfcrypt_FeatureDetect
* Method: Pbkdf2Enabled * Method: Pbkdf2Enabled
@ -199,6 +207,14 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_151
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_Pbkdf2Enabled JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_Pbkdf2Enabled
(JNIEnv *, jclass); (JNIEnv *, jclass);
/*
* Class: com_wolfssl_wolfcrypt_FeatureDetect
* Method: Pkcs12PbkdfEnabled
* Signature: ()Z
*/
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_Pkcs12PbkdfEnabled
(JNIEnv *, jclass);
/* /*
* Class: com_wolfssl_wolfcrypt_FeatureDetect * Class: com_wolfssl_wolfcrypt_FeatureDetect
* Method: RsaEnabled * Method: RsaEnabled

View File

@ -24,6 +24,7 @@
#elif !defined(__ANDROID__) #elif !defined(__ANDROID__)
#include <wolfssl/options.h> #include <wolfssl/options.h>
#endif #endif
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/asn_public.h> #include <wolfssl/wolfcrypt/asn_public.h>
#include <wolfssl/wolfcrypt/error-crypt.h> #include <wolfssl/wolfcrypt/error-crypt.h>
@ -76,3 +77,65 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Asn_getCTC_1HashOID(
{ {
return wc_GetCTC_HashOID(type); return wc_GetCTC_HashOID(type);
} }
JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_Asn_getPkcs8AlgoID
(JNIEnv* env, jclass class, jbyteArray pkcs8Der)
{
#if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
int ret = 0;
word32 algoId = 0;
byte* p8 = NULL;
byte* p8Copy = NULL;
word32 p8Len = 0;
if (pkcs8Der != NULL) {
p8 = (byte*)(*env)->GetByteArrayElements(env, pkcs8Der, NULL);
p8Len = (*env)->GetArrayLength(env, pkcs8Der);
}
if (p8 == NULL || p8Len == 0) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
p8Copy = (byte*)XMALLOC(p8Len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (p8Copy == NULL) {
ret = MEMORY_E;
}
}
if (ret == 0) {
/* Copy array since ToTraditional modifies source buffer */
XMEMSET(p8Copy, 0, p8Len);
XMEMCPY(p8Copy, p8, p8Len);
ret = ToTraditional_ex(p8Copy, p8Len, &algoId);
if (ret > 0) {
/* returns length of header, but not needed here */
ret = 0;
}
}
if (p8Copy != NULL) {
XMEMSET(p8Copy, 0, p8Len);
XFREE(p8Copy, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
if (pkcs8Der != NULL) {
(*env)->ReleaseByteArrayElements(env, pkcs8Der, (jbyte*)p8, JNI_ABORT);
}
if (ret == 0) {
ret = (int)algoId;
}
return (jint)ret;
#else
(void)env;
(void)class;
(void)pkcs8Der;
return (jint)NOT_COMPILED_IN;
#endif
}

View File

@ -304,6 +304,18 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_HmacSha3_151
#endif #endif
} }
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_Pbkdf1Enabled
(JNIEnv* env, jclass jcl)
{
(void)env;
(void)jcl;
#if !defined(NO_PWDBASED) && defined(HAVE_PBKDF1)
return JNI_TRUE;
#else
return JNI_FALSE;
#endif
}
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_Pbkdf2Enabled JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_Pbkdf2Enabled
(JNIEnv* env, jclass jcl) (JNIEnv* env, jclass jcl)
{ {
@ -316,6 +328,18 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_Pbkdf2Enable
#endif #endif
} }
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_Pkcs12PbkdfEnabled
(JNIEnv* env, jclass jcl)
{
(void)env;
(void)jcl;
#if !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
return JNI_TRUE;
#else
return JNI_FALSE;
#endif
}
JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_RsaEnabled JNIEXPORT jboolean JNICALL Java_com_wolfssl_wolfcrypt_FeatureDetect_RsaEnabled
(JNIEnv* env, jclass jcl) (JNIEnv* env, jclass jcl)
{ {

View File

@ -0,0 +1,131 @@
/* jni_jce_wolfsslkeystore.c
*
* Copyright (C) 2006-2024 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
*/
#ifdef WOLFSSL_USER_SETTINGS
#include <wolfssl/wolfcrypt/settings.h>
#elif !defined(__ANDROID__)
#include <wolfssl/options.h>
#endif
#include <wolfssl/ssl.h>
#include <com_wolfssl_provider_jce_WolfSSLKeyStore.h>
#include <wolfcrypt_jni_error.h>
/* #define WOLFCRYPT_JNI_DEBUG_ON */
#include <wolfcrypt_jni_debug.h>
JNIEXPORT jboolean JNICALL Java_com_wolfssl_provider_jce_WolfSSLKeyStore_X509CheckPrivateKey
(JNIEnv* env, jobject class, jbyteArray certDerArr, jbyteArray pkcs8KeyDerArr)
{
#if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) && defined(OPENSSL_EXTRA)
int ret = WOLFSSL_SUCCESS;
int certDerSz = 0;
int keyDerSz = 0;
byte* certDer = NULL;
byte* keyDer = NULL;
WOLFSSL_X509* x509 = NULL;
WOLFSSL_EVP_PKEY* key = NULL;
WOLFSSL_PKCS8_PRIV_KEY_INFO* keyInfo = NULL;
(void)class;
if (env == NULL || certDerArr == NULL || pkcs8KeyDerArr == NULL) {
throwWolfCryptExceptionFromError(env, BAD_FUNC_ARG);
return JNI_FALSE;
}
/* Get byte* and sizes from jbyteArrays */
certDer = (byte*)(*env)->GetByteArrayElements(env, certDerArr, NULL);
certDerSz = (*env)->GetArrayLength(env, certDerArr);
keyDer = (byte*)(*env)->GetByteArrayElements(env, pkcs8KeyDerArr, NULL);
keyDerSz = (*env)->GetArrayLength(env, pkcs8KeyDerArr);
if (certDer == NULL || certDerSz <= 0 || keyDer == NULL || keyDerSz <= 0) {
fprintf(stderr, "Native X509CheckPrivateKey() bad args");
ret = BAD_FUNC_ARG;
}
if (ret == WOLFSSL_SUCCESS) {
x509 = wolfSSL_X509_load_certificate_buffer(certDer, certDerSz,
WOLFSSL_FILETYPE_ASN1);
if (x509 == NULL) {
fprintf(stderr,
"Native wolfSSL_X509_load_certificate_buffer() failed");
ret = WOLFSSL_FAILURE;
}
}
if (ret == WOLFSSL_SUCCESS) {
keyInfo = wolfSSL_d2i_PKCS8_PKEY(NULL, (const byte**)&keyDer, keyDerSz);
if (keyInfo == NULL) {
fprintf(stderr, "Native wolfSSL_d2i_PKCS8_PKEY() failed");
ret = WOLFSSL_FAILURE;
}
}
if (ret == WOLFSSL_SUCCESS) {
key = wolfSSL_EVP_PKCS82PKEY(keyInfo);
if (key == NULL) {
fprintf(stderr, "Native wolfSSL_EVP_PKCS82PKEY() failed");
ret = WOLFSSL_FAILURE;
}
}
if (ret == WOLFSSL_SUCCESS) {
ret = wolfSSL_X509_check_private_key(x509, key);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "Native wolfSSL_X509_check_private_key() failed");
}
}
if (key != NULL) {
wolfSSL_EVP_PKEY_free(key);
}
if (x509 != NULL) {
wolfSSL_X509_free(x509);
}
if (certDer != NULL) {
(*env)->ReleaseByteArrayElements(env, certDerArr,
(jbyte*)certDer, JNI_ABORT);
}
if (keyDer != NULL) {
(*env)->ReleaseByteArrayElements(env, pkcs8KeyDerArr,
(jbyte*)keyDer, JNI_ABORT);
}
if (ret == WOLFSSL_SUCCESS) {
return JNI_TRUE;
}
else {
return JNI_FALSE;
}
#else
(void)env;
(void)class;
(void)certDer;
(void)pkcs8Der;
throwWolfCryptExceptionFromError(env, NOT_COMPILED_IN);
return JNI_FALSE;
#endif
}

View File

@ -132,6 +132,7 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Pwdbased_wc_1PBKDF2
if ((passBuf != NULL) && (passBufLen > 0)) { if ((passBuf != NULL) && (passBufLen > 0)) {
pass = (byte*)(*env)->GetByteArrayElements(env, passBuf, NULL); pass = (byte*)(*env)->GetByteArrayElements(env, passBuf, NULL);
} }
salt = (byte*)(*env)->GetByteArrayElements(env, saltBuf, NULL); salt = (byte*)(*env)->GetByteArrayElements(env, saltBuf, NULL);
ret = wc_PBKDF2(outKey, pass, passBufLen, salt, sBufLen, ret = wc_PBKDF2(outKey, pass, passBufLen, salt, sBufLen,
@ -155,6 +156,7 @@ JNIEXPORT jbyteArray JNICALL Java_com_wolfssl_wolfcrypt_Pwdbased_wc_1PBKDF2
if (pass != NULL) { if (pass != NULL) {
(*env)->ReleaseByteArrayElements(env, passBuf, (jbyte*)pass, JNI_ABORT); (*env)->ReleaseByteArrayElements(env, passBuf, (jbyte*)pass, JNI_ABORT);
} }
(*env)->ReleaseByteArrayElements(env, saltBuf, (jbyte*)salt, JNI_ABORT); (*env)->ReleaseByteArrayElements(env, saltBuf, (jbyte*)salt, JNI_ABORT);
if (ret != 0) { if (ret != 0) {

View File

@ -27,6 +27,7 @@
#include <wolfssl/options.h> #include <wolfssl/options.h>
#endif #endif
#include <wolfssl/wolfcrypt/types.h>
#include <com_wolfssl_wolfcrypt_WolfCrypt.h> #include <com_wolfssl_wolfcrypt_WolfCrypt.h>
#include <wolfcrypt_jni_error.h> #include <wolfcrypt_jni_error.h>

View File

@ -31,7 +31,7 @@ OBJ_LIST = jni_fips.o jni_native_struct.o jni_pwdbased.o jni_aes.o \
jni_rng.o jni_rsa.o jni_dh.o jni_ecc.o jni_ed25519.o \ jni_rng.o jni_rsa.o jni_dh.o jni_ecc.o jni_ed25519.o \
jni_curve25519.o jni_chacha.o jni_error.o jni_asn.o jni_logging.o \ jni_curve25519.o jni_chacha.o jni_error.o jni_asn.o jni_logging.o \
jni_feature_detect.o jni_wolfobject.o jni_wolfcrypt.o \ jni_feature_detect.o jni_wolfobject.o jni_wolfcrypt.o \
jni_wolfssl_cert_manager.o jni_wolfssl_cert_manager.o jni_jce_wolfsslkeystore.o
OBJS = $(patsubst %,$(OUT_PATH)/%,$(OBJ_LIST)) OBJS = $(patsubst %,$(OUT_PATH)/%,$(OBJ_LIST))
TARGET = $(OUT_PATH)/libwolfcryptjni.so TARGET = $(OUT_PATH)/libwolfcryptjni.so

View File

@ -25,7 +25,7 @@ OBJ_LIST = jni_fips.o jni_native_struct.o jni_pwdbased.o jni_aes.o \
jni_rsa.o jni_dh.o jni_ecc.o jni_ed25519.o jni_curve25519.o \ jni_rsa.o jni_dh.o jni_ecc.o jni_ed25519.o jni_curve25519.o \
jni_chacha.o jni_error.o jni_asn.o jni_logging.o \ jni_chacha.o jni_error.o jni_asn.o jni_logging.o \
jni_feature_detect.o jni_wolfobject.o jni_wolfcrypt.o \ jni_feature_detect.o jni_wolfobject.o jni_wolfcrypt.o \
jni_wolfssl_cert_manager.o jni_wolfssl_cert_manager.o jni_jce_wolfsslkeystore.o
OBJS = $(patsubst %,$(OUT_PATH)/%,$(OBJ_LIST)) OBJS = $(patsubst %,$(OUT_PATH)/%,$(OBJ_LIST))
TARGET = $(OUT_PATH)/libwolfcryptjni.dylib TARGET = $(OUT_PATH)/libwolfcryptjni.dylib

View File

@ -78,6 +78,7 @@ infer --fail-on-issue run -- javac \
src/main/java/com/wolfssl/provider/jce/WolfCryptRandom.java \ src/main/java/com/wolfssl/provider/jce/WolfCryptRandom.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptSecretKeyFactory.java \ src/main/java/com/wolfssl/provider/jce/WolfCryptSecretKeyFactory.java \
src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java
src/main/java/com/wolfssl/provider/jce/WolfSSLKeyStore.java
RETVAL=$? RETVAL=$?

View File

@ -172,10 +172,6 @@ public final class WolfCryptProvider extends Provider {
put("Alg.Alias.KeyPairGenerator.DiffieHellman", "DH"); put("Alg.Alias.KeyPairGenerator.DiffieHellman", "DH");
} }
/* KeyStore */
put("KeyStore.WKS",
"com.wolfssl.provider.jce.WolfSSLKeyStore$WolfSSLKeyStoreWKS");
/* CertPathValidator */ /* CertPathValidator */
put("CertPathValidator.PKIX", put("CertPathValidator.PKIX",
"com.wolfssl.provider.jce.WolfCryptPKIXCertPathValidator"); "com.wolfssl.provider.jce.WolfCryptPKIXCertPathValidator");
@ -220,6 +216,10 @@ public final class WolfCryptProvider extends Provider {
} }
} }
/* KeyStore */
put("KeyStore.WKS",
"com.wolfssl.provider.jce.WolfSSLKeyStore");
/* If using a FIPS version of wolfCrypt, allow private key to be /* If using a FIPS version of wolfCrypt, allow private key to be
* exported for use. Only applicable to FIPS 140-3 */ * exported for use. Only applicable to FIPS 140-3 */
if (Fips.enabled) { if (Fips.enabled) {

View File

@ -251,7 +251,7 @@ public class WolfCryptSecretKeyFactory extends SecretKeyFactorySpi {
* @return password as UTF-8 encoded byte array, or null if input password * @return password as UTF-8 encoded byte array, or null if input password
* is null or zero length * is null or zero length
*/ */
private static byte[] passwordToByteArray(char[] pass) { protected static byte[] passwordToByteArray(char[] pass) {
byte[] passBytes = null; byte[] passBytes = null;
CharBuffer passBuf = null; CharBuffer passBuf = null;

View File

@ -301,11 +301,11 @@ public class WolfCryptSignature extends SignatureSpi {
if (this.keyType == KeyType.WC_RSA && if (this.keyType == KeyType.WC_RSA &&
!(publicKey instanceof RSAPublicKey)) { !(publicKey instanceof RSAPublicKey)) {
throw new InvalidKeyException("Key is not of type RSAPrivateKey"); throw new InvalidKeyException("Key is not of type RSAPublicKey");
} else if (this.keyType == KeyType.WC_ECDSA && } else if (this.keyType == KeyType.WC_ECDSA &&
!(publicKey instanceof ECPublicKey)) { !(publicKey instanceof ECPublicKey)) {
throw new InvalidKeyException("Key is not of type ECPrivateKey"); throw new InvalidKeyException("Key is not of type ECPublicKey");
} }
/* get encoded key, returns PKCS#8 formatted private key */ /* get encoded key, returns PKCS#8 formatted private key */

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,19 @@ public class Asn extends WolfObject {
/** Maximum encoded signature size */ /** Maximum encoded signature size */
public static final int MAX_ENCODED_SIG_SIZE = 512; public static final int MAX_ENCODED_SIG_SIZE = 512;
/* Key Sum values, from asn.h Key_Sum enum */
/** DSA key value, from asn.h Key_Sum enum */
public static final int DSAk = 515;
/** RSA key value, from asn.h Key_Sum enum */
public static final int RSAk = 645;
/** RSA-PSS key value, from asn.h Key_Sum enum */
public static final int RSAPSSk = 654;
/** RSA-OAEP key value, from asn.h Key_Sum enum */
public static final int RSAESOAEPk = 651;
/** ECDSA key value, from asn.h Key_Sum enum */
public static final int ECDSAk = 518;
/** Default Asn constructor */ /** Default Asn constructor */
public Asn() { } public Asn() { }
@ -67,5 +80,17 @@ public class Asn extends WolfObject {
* @return hash algorithm OID, for use with encodeSignature() * @return hash algorithm OID, for use with encodeSignature()
*/ */
public static native int getCTC_HashOID(int type); public static native int getCTC_HashOID(int type);
/**
* Get the Algorithm Identifier from inside DER-encoded PKCS#8 key.
*
* @param pkcs8Der DER-encoded PKCS#8 private key
*
* @return Algorithm Identifier on success, will match one of the values
* for key sums (ie: Asn.RSAk, Asn.ECDSAk, etc)
*
* @throws WolfCryptException upon native error
*/
public static native int getPkcs8AlgoID(byte[] pkcs8Der);
} }

View File

@ -195,6 +195,14 @@ public class FeatureDetect {
*/ */
public static native boolean HmacSha3_512Enabled(); public static native boolean HmacSha3_512Enabled();
/**
* Tests if PKCS#5 PBKDF1 is compiled into the native wolfSSL library.
*
* @return true if PBKDF1 is enabled (HAVE_PBKDF1, !NO_PWDBASED),
* otherwise false.
*/
public static native boolean Pbkdf1Enabled();
/** /**
* Tests if PKCS#5 v2.1 PBKDF2 is compiled into the native wolfSSL library. * Tests if PKCS#5 v2.1 PBKDF2 is compiled into the native wolfSSL library.
* *
@ -203,6 +211,14 @@ public class FeatureDetect {
*/ */
public static native boolean Pbkdf2Enabled(); public static native boolean Pbkdf2Enabled();
/**
* Tests if PKCS#12 PBKDF is compiled into the native wolfSSL library.
*
* @return true if PKCS#12 PBKDF is enabled (HAVE_PKCS12, !NO_PWDBASED),
* otherwise false.
*/
public static native boolean Pkcs12PbkdfEnabled();
/** /**
* Tests if RSA is compiled into the native wolfSSL library. * Tests if RSA is compiled into the native wolfSSL library.
* *

View File

@ -150,6 +150,34 @@ public class WolfCrypt extends WolfObject {
*/ */
public static native boolean CrlEnabled(); public static native boolean CrlEnabled();
/**
* Constant time byte array comparison.
*
* If arrays are of different lengths, return false right away. Apart
* from length check, this matches native wolfSSL ConstantCompare()
* logic in misc.c.
*
* @param a first byte array for comparison
* @param b second byte array for comparison
*
* @return true if equal, otherwise false
*/
public static boolean ConstantCompare(byte[] a, byte[] b) {
int i;
int compareSum = 0;
if (a.length != b.length) {
return false;
}
for (i = 0; i < a.length; i++) {
compareSum |= a[i] ^ b[i];
}
return (compareSum == 0);
}
private WolfCrypt() { private WolfCrypt() {
} }
} }

View File

@ -39,7 +39,8 @@ import org.junit.runners.Suite.SuiteClasses;
WolfCryptCipherTest.class, WolfCryptCipherTest.class,
WolfCryptKeyAgreementTest.class, WolfCryptKeyAgreementTest.class,
WolfCryptKeyPairGeneratorTest.class, WolfCryptKeyPairGeneratorTest.class,
WolfCryptPKIXCertPathValidatorTest.class WolfCryptPKIXCertPathValidatorTest.class,
WolfSSLKeyStoreTest.class
}) })
public class WolfJCETestSuite { } public class WolfJCETestSuite { }

File diff suppressed because it is too large Load Diff

View File

@ -27,21 +27,21 @@ import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class) @RunWith(Suite.class)
@SuiteClasses({ @SuiteClasses({
AesTest.class, AesTest.class,
AesGcmTest.class, AesGcmTest.class,
Des3Test.class, Des3Test.class,
ChachaTest.class, ChachaTest.class,
Md5Test.class, Md5Test.class,
ShaTest.class, ShaTest.class,
Sha256Test.class, Sha256Test.class,
Sha384Test.class, Sha384Test.class,
Sha512Test.class, Sha512Test.class,
HmacTest.class, HmacTest.class,
RngTest.class, RngTest.class,
RsaTest.class, RsaTest.class,
DhTest.class, DhTest.class,
EccTest.class EccTest.class
}) })
public class WolfCryptTestSuite { public class WolfCryptTestSuite {
} }