Skip to content

Commit

Permalink
Merge pull request #533 from Bhashinee/versionUpdate
Browse files Browse the repository at this point in the history
Introduce new APIs to read EC private keys and public keys
Bhashinee authored Dec 6, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
2 parents 0c97dc2 + 6f1b573 commit 1f4311f
Showing 13 changed files with 302 additions and 35 deletions.
6 changes: 3 additions & 3 deletions ballerina/Ballerina.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
org = "ballerina"
name = "crypto"
version = "2.5.0"
version = "2.6.0"
authors = ["Ballerina"]
keywords = ["security", "hash", "hmac", "sign", "encrypt", "decrypt", "private key", "public key"]
repository = "https://github.com/ballerina-platform/module-ballerina-crypto"
@@ -15,8 +15,8 @@ graalvmCompatible = true
[[platform.java17.dependency]]
groupId = "io.ballerina.stdlib"
artifactId = "crypto-native"
version = "2.5.0"
path = "../native/build/libs/crypto-native-2.5.0.jar"
version = "2.6.0"
path = "../native/build/libs/crypto-native-2.6.0-SNAPSHOT.jar"

[[platform.java17.dependency]]
groupId = "org.bouncycastle"
2 changes: 1 addition & 1 deletion ballerina/Dependencies.toml
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ distribution-version = "2201.8.0"
[[package]]
org = "ballerina"
name = "crypto"
version = "2.5.0"
version = "2.6.0"
dependencies = [
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "test"},
35 changes: 35 additions & 0 deletions ballerina/private_public_key.bal
Original file line number Diff line number Diff line change
@@ -96,6 +96,24 @@ public isolated function decodeRsaPrivateKeyFromKeyStore(KeyStore keyStore, stri
'class: "io.ballerina.stdlib.crypto.nativeimpl.Decode"
} external;

# Decodes the EC private key from the given PKCS#12 archive file.
# ```ballerina
# crypto:KeyStore keyStore = {
# path: "/path/to/keyStore.p12",
# password: "keyStorePassword"
# };
# crypto:PrivateKey privateKey = check crypto:decodeEcPrivateKeyFromKeyStore(keyStore, "keyAlias", "keyPassword");
# ```
#
# + keyStore - KeyStore configurations
# + keyAlias - Key alias
# + keyPassword - Key password
# + return - Reference to the private key or else a `crypto:Error` if the private key was unreadable
public isolated function decodeEcPrivateKeyFromKeyStore(KeyStore keyStore, string keyAlias, string keyPassword)
returns PrivateKey|Error = @java:Method {
'class: "io.ballerina.stdlib.crypto.nativeimpl.Decode"
} external;

# Decodes the RSA private key from the given private key and private key password.
# ```ballerina
# string keyFile = "/path/to/private.key";
@@ -127,6 +145,23 @@ public isolated function decodeRsaPublicKeyFromTrustStore(TrustStore trustStore,
'class: "io.ballerina.stdlib.crypto.nativeimpl.Decode"
} external;

# Decodes the EC public key from the given PKCS#12 archive file.
# ```ballerina
# crypto:TrustStore trustStore = {
# path: "/path/tp/truststore.p12",
# password: "truststorePassword"
# };
# crypto:PublicKey publicKey = check crypto:decodeEcPublicKeyFromTrustStore(trustStore, "keyAlias");
# ```
#
# + trustStore - TrustStore configurations
# + keyAlias - Key alias
# + return - Reference to the public key or else a `crypto:Error` if the public key was unreadable
public isolated function decodeEcPublicKeyFromTrustStore(TrustStore trustStore, string keyAlias)
returns PublicKey|Error = @java:Method {
'class: "io.ballerina.stdlib.crypto.nativeimpl.Decode"
} external;

# Decodes the RSA public key from the given public certificate file.
# ```ballerina
# string certFile = "/path/to/public.cert";
44 changes: 44 additions & 0 deletions ballerina/sign_verify.bal
Original file line number Diff line number Diff line change
@@ -116,6 +116,26 @@ public isolated function signRsaSha512(byte[] input, PrivateKey privateKey) retu
'class: "io.ballerina.stdlib.crypto.nativeimpl.Sign"
} external;

# Returns the SHA384withECDSA based signature value for the given data.
# ```ballerina
# string input = "Hello Ballerina";
# byte[] data = input.toBytes();
# crypto:KeyStore keyStore = {
# path: "/path/to/keyStore.p12",
# password: "keyStorePassword"
# };
# crypto:PrivateKey privateKey = check crypto:decodeEcPrivateKeyFromKeyStore(keyStore, "keyAlias", "keyPassword");
# byte[] signature = check crypto:signSha384withEcdsa(data, privateKey);
# ```
#
# + input - The content to be signed
# + privateKey - Private key used for signing
# + return - The generated signature or else a `crypto:Error` if the private key is invalid
public isolated function signSha384withEcdsa(byte[] input, PrivateKey privateKey) returns byte[]|Error = @java:Method {
name: "signSha384withEcdsa",
'class: "io.ballerina.stdlib.crypto.nativeimpl.Sign"
} external;

# Verifies the RSA-MD5 based signature.
# ```ballerina
# string input = "Hello Ballerina";
@@ -235,3 +255,27 @@ public isolated function verifyRsaSha512Signature(byte[] data, byte[] signature,
name: "verifyRsaSha512Signature",
'class: "io.ballerina.stdlib.crypto.nativeimpl.Sign"
} external;

# Verifies the SHA384withECDSA based signature.
# ```ballerina
# string input = "Hello Ballerina";
# byte[] data = input.toBytes();
# crypto:KeyStore keyStore = {
# path: "/path/to/keyStore.p12",
# password: "keyStorePassword"
# };
# crypto:PrivateKey privateKey = check crypto:decodeEcPrivateKeyFromKeyStore(keyStore, "keyAlias", "keyPassword");
# byte[] signature = check crypto:signSha384withEcdsa(data, privateKey);
# crypto:PublicKey publicKey = check crypto:decodeEcPublicKeyFromTrustStore(keyStore, "keyAlias");
# boolean validity = check crypto:verifySha384withEcdsaSignature(data, signature, publicKey);
# ```
#
# + data - The content to be verified
# + signature - Signature value
# + publicKey - Public key used for verification
# + return - Validity of the signature or else a `crypto:Error` if the public key is invalid
public isolated function verifySha384withEcdsaSignature(byte[] data, byte[] signature, PublicKey publicKey)
returns boolean|Error = @java:Method {
name: "verifySha384withEcdsaSignature",
'class: "io.ballerina.stdlib.crypto.nativeimpl.Sign"
} external;
Binary file added ballerina/tests/resources/ec-keystore.pkcs12
Binary file not shown.
69 changes: 69 additions & 0 deletions ballerina/tests/sign_verify_test.bal
Original file line number Diff line number Diff line change
@@ -230,3 +230,72 @@ isolated function testVerifyRsaSha512() returns Error? {
byte[] sha512Signature = check signRsaSha512(payload, privateKey);
test:assertTrue(check verifyRsaSha512Signature(payload, sha512Signature, publicKey));
}

@test:Config {}
isolated function testVerifySha384withEcdsa() returns Error? {
byte[] payload = "Ballerina test".toBytes();
KeyStore keyStore = {
path: EC_KEYSTORE_PATH,
password: "ballerina"
};
PrivateKey privateKey = check decodeEcPrivateKeyFromKeyStore(keyStore, "ec-keypair", "ballerina");
PublicKey publicKey = check decodeEcPublicKeyFromTrustStore(keyStore, "ec-keypair");
byte[] sha384withEcdsaSignature = check signSha384withEcdsa(payload, privateKey);
test:assertTrue(check verifySha384withEcdsaSignature(payload, sha384withEcdsaSignature, publicKey));
}

@test:Config {}
isolated function testDecodeRsaPrivateKeyError() returns Error? {
KeyStore keyStore = {
path: EC_KEYSTORE_PATH,
password: "ballerina"
};
PrivateKey|Error privateKey = decodeRsaPrivateKeyFromKeyStore(keyStore, "ec-keypair", "ballerina");
if privateKey is Error {
test:assertEquals(privateKey.message(), "Not a valid RSA key");
} else {
test:assertFail("Expected error not found");
}
}

@test:Config {}
isolated function testDecodeEcPrivateKeyError() returns Error? {
KeyStore keyStore = {
path: KEYSTORE_PATH,
password: "ballerina"
};
PrivateKey|Error privateKey = decodeEcPrivateKeyFromKeyStore(keyStore, "ballerina", "ballerina");
if privateKey is Error {
test:assertEquals(privateKey.message(), "Not a valid EC key");
} else {
test:assertFail("Expected error not found");
}
}

@test:Config {}
isolated function testDecodeEcPublicKeyError() returns Error? {
KeyStore keyStore = {
path: KEYSTORE_PATH,
password: "ballerina"
};
PublicKey|Error publicKey = decodeEcPublicKeyFromTrustStore(keyStore, "ballerina");
if publicKey is Error {
test:assertEquals(publicKey.message(), "Not a valid EC public key");
} else {
test:assertFail("Expected error not found");
}
}

@test:Config {}
isolated function testDecodeRsaPublicKeyError() returns Error? {
KeyStore keyStore = {
path: EC_KEYSTORE_PATH,
password: "ballerina"
};
PublicKey|Error publicKey = decodeRsaPublicKeyFromTrustStore(keyStore, "ec-keypair");
if publicKey is Error {
test:assertEquals(publicKey.message(), "Not a valid RSA public key");
} else {
test:assertFail("Expected error not found");
}
}
1 change: 1 addition & 0 deletions ballerina/tests/test_utils.bal
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
// under the License.

const string KEYSTORE_PATH = "tests/resources/keyStore.p12";
const string EC_KEYSTORE_PATH = "tests/resources/ec-keystore.pkcs12";
const string ENCRYPTED_KEY_PAIR_PATH = "tests/resources/encryptedKeyPair.pem";
const string KEY_PAIR_PATH = "tests/resources/keyPair.pem";
const string ENCRYPTED_PRIVATE_KEY_PATH = "tests/resources/encryptedPrivate.key";
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Added
- [Introduce new APIs to interact with EC private keys and public keys](https://github.com/ballerina-platform/ballerina-library/issues/5821)

## [2.5.0] - 2023-09-15

### Changed
34 changes: 34 additions & 0 deletions docs/spec/spec.md
Original file line number Diff line number Diff line change
@@ -55,12 +55,14 @@ The conforming implementation of the specification is released and included in t
* 6.1.3. [RSA-SHA256](#613-rsa-sha256)
* 6.1.4. [RSA-SHA384](#614-rsa-sha384)
* 6.1.5. [RSA-SHA512](#615-rsa-sha512)
* 6.1.6. [SHA384withECDSA](#616-sha384withecdsa)
* 6.2. [Verify signature](#62-verify-signature)
* 6.2.1. [RSA-MD5](#621-rsa-md5)
* 6.2.2. [RSA-SHA1](#622-rsa-sha1)
* 6.2.3. [RSA-SHA256](#623-rsa-sha256)
* 6.2.4. [RSA-SHA384](#624-rsa-sha384)
* 6.2.5. [RSA-SHA512](#625-rsa-sha512)
* 6.2.6. [SHA384withECDSA](#626-sha384withecdsa)

## 1. [Overview](#1-overview)

@@ -471,6 +473,21 @@ crypto:PrivateKey privateKey = check crypto:decodeRsaPrivateKeyFromKeyStore(keyS
byte[] signature = check crypto:signRsaSha512(data, privateKey);
```

#### 6.1.6. [SHA384withECDSA](#616-sha384withecdsa)

This API can be used to create the SHA384withECDSA based signature value for the given data.

```ballerina
string input = "Hello Ballerina";
byte[] data = input.toBytes();
crypto:KeyStore keyStore = {
path: "/path/to/keyStore.p12",
password: "keyStorePassword"
};
crypto:PrivateKey privateKey = check crypto:decodeEcPrivateKeyFromKeyStore(keyStore, "keyAlias", "keyPassword");
byte[] signature = check crypto:signSha384withEcdsa(data, privateKey);
```

### 6.2. [Verify signature](#62-verify-signature)

#### 6.2.1. [RSA-MD5](#621-rsa-md5)
@@ -557,3 +574,20 @@ byte[] signature = check crypto:signRsaSha512(data, privateKey);
crypto:PublicKey publicKey = check crypto:decodeRsaPublicKeyFromTrustStore(keyStore, "keyAlias");
boolean validity = check crypto:verifyRsaSha512Signature(data, signature, publicKey);
```

#### 6.2.6. [SHA384withECDSA](#626-sha384withecdsa)

This API can be used to verify the SHA384withECDSA based signature.

```ballerina
string input = "Hello Ballerina";
byte[] data = input.toBytes();
crypto:KeyStore keyStore = {
path: "/path/to/keyStore.p12",
password: "keyStorePassword"
};
crypto:PrivateKey privateKey = check crypto:decodeEcPrivateKeyFromKeyStore(keyStore, "keyAlias", "keyPassword");
byte[] signature = check crypto:signSha384withEcdsa(data, privateKey);
crypto:PublicKey publicKey = check crypto:decodeEcPublicKeyFromTrustStore(keyStore, "keyAlias");
boolean validity = check crypto:verifySha384withEcdsaSignature(data, signature, publicKey);
```
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
org.gradle.caching=true
group=io.ballerina.stdlib
version=2.5.1-SNAPSHOT
version=2.6.0-SNAPSHOT
puppycrawlCheckstyleVersion=10.12.0
bouncycastleVersion=1.74
githubSpotbugsVersion=5.0.14
Original file line number Diff line number Diff line change
@@ -42,6 +42,8 @@ private Constants() {}
// Native data key for private key within the PrivateKey record.
public static final String NATIVE_DATA_PRIVATE_KEY = "NATIVE_DATA_PRIVATE_KEY";

public static final String NATIVE_DATA_EC_PRIVATE_KEY = "NATIVE_DATA_EC_PRIVATE_KEY";

// Native data key for private key within the PublicKey record.
public static final String NATIVE_DATA_PUBLIC_KEY = "NATIVE_DATA_PUBLIC_KEY";

@@ -97,6 +99,9 @@ private Constants() {}
// RSA key algorithm
public static final String RSA_ALGORITHM = "RSA";

// EC key algorithm
public static final String EC_ALGORITHM = "EC";

// GMT timezone name used for X509 validity times
public static final String TIMEZONE_GMT = "GMT";

123 changes: 93 additions & 30 deletions native/src/main/java/io/ballerina/stdlib/crypto/nativeimpl/Decode.java
Original file line number Diff line number Diff line change
@@ -73,6 +73,24 @@ private Decode() {}

public static Object decodeRsaPrivateKeyFromKeyStore(BMap<BString, BString> keyStoreRecord, BString keyAlias,
BString keyPassword) {
Object decodedPrivateKey = getPrivateKey(keyStoreRecord, keyAlias, keyPassword);
if (decodedPrivateKey instanceof PrivateKey privateKey) {
return buildRsPrivateKeyRecord(privateKey);
}
return decodedPrivateKey;
}

public static Object decodeEcPrivateKeyFromKeyStore(BMap<BString, BString> keyStoreRecord, BString keyAlias,
BString keyPassword) {

Object decodedPrivateKey = getPrivateKey(keyStoreRecord, keyAlias, keyPassword);
if (decodedPrivateKey instanceof PrivateKey privateKey) {
return buildEcPrivateKeyRecord(privateKey);
}
return decodedPrivateKey;
}

private static Object getPrivateKey(BMap<BString, BString> keyStoreRecord, BString keyAlias, BString keyPassword) {
File keyStoreFile = new File(keyStoreRecord.get(Constants.KEY_STORE_RECORD_PATH_FIELD).toString());
try (FileInputStream fileInputStream = new FileInputStream(keyStoreFile)) {
KeyStore keyStore = KeyStore.getInstance(Constants.KEYSTORE_TYPE_PKCS12);
@@ -84,11 +102,11 @@ public static Object decodeRsaPrivateKeyFromKeyStore(BMap<BString, BString> keyS
}

PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias.getValue(),
keyPassword.getValue().toCharArray());
keyPassword.getValue().toCharArray());
if (privateKey == null) {
return CryptoUtils.createError("Key cannot be recovered by using given key alias: " + keyAlias);
}
return buildPrivateKeyRecord(privateKey);
return privateKey;
} catch (FileNotFoundException e) {
return CryptoUtils.createError("PKCS12 KeyStore not found at: " + keyStoreFile.getAbsoluteFile());
} catch (KeyStoreException | CertificateException | IOException e) {
@@ -133,28 +151,55 @@ public static Object decodeRsaPrivateKeyFromKeyFile(BString keyFilePath, Object
keyFilePath.getValue());
}
PrivateKey privateKey = converter.getPrivateKey(privateKeyInfo);
return buildPrivateKeyRecord(privateKey);
return buildRsPrivateKeyRecord(privateKey);
} catch (FileNotFoundException e) {
return CryptoUtils.createError("Key file not found at: " + privateKeyFile.getAbsoluteFile());
} catch (PKCSException | IOException e) {
return CryptoUtils.createError("Unable to do private key operations: " + e.getMessage());
}
}

private static Object buildPrivateKeyRecord(PrivateKey privateKey) {
private static Object buildRsPrivateKeyRecord(PrivateKey privateKey) {
if (privateKey.getAlgorithm().equals(Constants.RSA_ALGORITHM)) {
BMap<BString, Object> privateKeyRecord = ValueCreator.
createRecordValue(ModuleUtils.getModule(), Constants.PRIVATE_KEY_RECORD);
privateKeyRecord.addNativeData(Constants.NATIVE_DATA_PRIVATE_KEY, privateKey);
privateKeyRecord.put(StringUtils.fromString(Constants.PRIVATE_KEY_RECORD_ALGORITHM_FIELD),
StringUtils.fromString(privateKey.getAlgorithm()));
return privateKeyRecord;
return getPrivateKeyRecord(privateKey);
} else {
return CryptoUtils.createError("Not a valid RSA key.");
return CryptoUtils.createError("Not a valid RSA key");
}
}

private static Object getPrivateKeyRecord(PrivateKey privateKey) {
BMap<BString, Object> privateKeyRecord = ValueCreator.
createRecordValue(ModuleUtils.getModule(), Constants.PRIVATE_KEY_RECORD);
privateKeyRecord.addNativeData(Constants.NATIVE_DATA_PRIVATE_KEY, privateKey);
privateKeyRecord.put(StringUtils.fromString(Constants.PRIVATE_KEY_RECORD_ALGORITHM_FIELD),
StringUtils.fromString(privateKey.getAlgorithm()));
return privateKeyRecord;
}

private static Object buildEcPrivateKeyRecord(PrivateKey privateKey) {
if (privateKey.getAlgorithm().equals(Constants.EC_ALGORITHM)) {
return getPrivateKeyRecord(privateKey);
}
return CryptoUtils.createError("Not a valid EC key");
}

public static Object decodeRsaPublicKeyFromTrustStore(BMap<BString, BString> trustStoreRecord, BString keyAlias) {
Object certificate = getPublicKey(trustStoreRecord, keyAlias);
if (certificate instanceof Certificate publicKey) {
return buildRsaPublicKeyRecord(publicKey);
}
return certificate;
}

public static Object decodeEcPublicKeyFromTrustStore(BMap<BString, BString> trustStoreRecord, BString keyAlias) {
Object certificate = getPublicKey(trustStoreRecord, keyAlias);
if (certificate instanceof Certificate publicKey) {
return buildEcPublicKeyRecord(publicKey);
}
return certificate;
}

private static Object getPublicKey(BMap<BString, BString> trustStoreRecord, BString keyAlias) {
File keyStoreFile = new File(trustStoreRecord.get(Constants.KEY_STORE_RECORD_PATH_FIELD).toString());
try (FileInputStream fileInputStream = new FileInputStream(keyStoreFile)) {
KeyStore keyStore = KeyStore.getInstance(Constants.KEYSTORE_TYPE_PKCS12);
@@ -169,7 +214,7 @@ public static Object decodeRsaPublicKeyFromTrustStore(BMap<BString, BString> tru
if (certificate == null) {
return CryptoUtils.createError("Certificate cannot be recovered by using given key alias: " + keyAlias);
}
return buildPublicKeyRecord(certificate);
return certificate;
} catch (FileNotFoundException e) {
return CryptoUtils.createError("PKCS12 KeyStore not found at: " + keyStoreFile.getAbsoluteFile());
} catch (KeyStoreException | CertificateException | IOException e) {
@@ -182,15 +227,48 @@ public static Object decodeRsaPublicKeyFromCertFile(BString certFilePath) {
try (FileInputStream fileInputStream = new FileInputStream(certFile)) {
CertificateFactory certificateFactory = CertificateFactory.getInstance(Constants.CERTIFICATE_TYPE_X509);
X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(fileInputStream);
return buildPublicKeyRecord(certificate);
return buildRsaPublicKeyRecord(certificate);
} catch (FileNotFoundException e) {
return CryptoUtils.createError("Certificate file not found at: " + certFile.getAbsolutePath());
} catch (CertificateException | IOException e) {
return CryptoUtils.createError("Unable to do public key operations: " + e.getMessage());
}
}

private static Object buildPublicKeyRecord(Certificate certificate) {
private static Object buildRsaPublicKeyRecord(Certificate certificate) {
BMap<BString, Object> certificateBMap = enrichPublicKeyInfo(certificate);
PublicKey publicKey = certificate.getPublicKey();
if (publicKey.getAlgorithm().equals(Constants.RSA_ALGORITHM)) {
return getPublicKeyRecord(certificate, certificateBMap, publicKey);
}
return CryptoUtils.createError("Not a valid RSA public key");
}

private static Object buildEcPublicKeyRecord(Certificate certificate) {
BMap<BString, Object> certificateBMap = enrichPublicKeyInfo(certificate);
PublicKey publicKey = certificate.getPublicKey();
if (publicKey.getAlgorithm().equals(Constants.EC_ALGORITHM)) {
return getPublicKeyRecord(certificate, certificateBMap, publicKey);
}
return CryptoUtils.createError("Not a valid EC public key");
}

private static Object getPublicKeyRecord(Certificate certificate, BMap<BString, Object> certificateBMap,
PublicKey publicKey) {
BMap<BString, Object> publicKeyMap = ValueCreator.
createRecordValue(ModuleUtils.getModule(), Constants.PUBLIC_KEY_RECORD);
publicKeyMap.addNativeData(Constants.NATIVE_DATA_PUBLIC_KEY, publicKey);
publicKeyMap.addNativeData(Constants.NATIVE_DATA_PUBLIC_KEY_CERTIFICATE, certificate);
publicKeyMap.put(StringUtils.fromString(Constants.PUBLIC_KEY_RECORD_ALGORITHM_FIELD),
StringUtils.fromString(publicKey.getAlgorithm()));
if (certificateBMap.size() > 0) {
publicKeyMap.put(StringUtils.fromString(Constants.PUBLIC_KEY_RECORD_CERTIFICATE_FIELD),
certificateBMap);
}
return publicKeyMap;
}

private static BMap<BString, Object> enrichPublicKeyInfo(Certificate certificate) {
BMap<BString, Object> certificateBMap = ValueCreator.
createRecordValue(ModuleUtils.getModule(), Constants.CERTIFICATE_RECORD);
if (certificate instanceof X509Certificate) {
@@ -214,22 +292,7 @@ private static Object buildPublicKeyRecord(Certificate certificate) {
certificateBMap.put(StringUtils.fromString(Constants.CERTIFICATE_RECORD_SIGNATURE_ALG_FIELD),
StringUtils.fromString(x509Certificate.getSigAlgName()));
}
PublicKey publicKey = certificate.getPublicKey();
if (publicKey.getAlgorithm().equals(Constants.RSA_ALGORITHM)) {
BMap<BString, Object> publicKeyMap = ValueCreator.
createRecordValue(ModuleUtils.getModule(), Constants.PUBLIC_KEY_RECORD);
publicKeyMap.addNativeData(Constants.NATIVE_DATA_PUBLIC_KEY, publicKey);
publicKeyMap.addNativeData(Constants.NATIVE_DATA_PUBLIC_KEY_CERTIFICATE, certificate);
publicKeyMap.put(StringUtils.fromString(Constants.PUBLIC_KEY_RECORD_ALGORITHM_FIELD),
StringUtils.fromString(publicKey.getAlgorithm()));
if (certificateBMap.size() > 0) {
publicKeyMap.put(StringUtils.fromString(Constants.PUBLIC_KEY_RECORD_CERTIFICATE_FIELD),
certificateBMap);
}
return publicKeyMap;
} else {
return CryptoUtils.createError("Not a valid RSA key.");
}
return certificateBMap;
}

public static Object buildRsaPublicKey(BString modulus, BString exponent) {
Original file line number Diff line number Diff line change
@@ -59,6 +59,12 @@ public static Object signRsaSha384(BArray inputValue, BMap<?, ?> privateKey) {
return CryptoUtils.sign("SHA384withRSA", key, input);
}

public static Object signSha384withEcdsa(BArray inputValue, BMap<?, ?> privateKey) {
byte[] input = inputValue.getBytes();
PrivateKey key = (PrivateKey) privateKey.getNativeData(Constants.NATIVE_DATA_PRIVATE_KEY);
return CryptoUtils.sign("SHA384withECDSA", key, input);
}

public static Object signRsaSha512(BArray inputValue, BMap<?, ?> privateKey) {
byte[] input = inputValue.getBytes();
PrivateKey key = (PrivateKey) privateKey.getNativeData(Constants.NATIVE_DATA_PRIVATE_KEY);
@@ -104,4 +110,11 @@ public static Object verifyRsaSha512Signature(BArray dataValue, BArray signature
PublicKey key = (PublicKey) publicKey.getNativeData(Constants.NATIVE_DATA_PUBLIC_KEY);
return CryptoUtils.verify("SHA512withRSA", key, data, signature);
}

public static Object verifySha384withEcdsaSignature(BArray dataValue, BArray signatureValue, BMap<?, ?> publicKey) {
byte[] data = dataValue.getBytes();
byte[] signature = signatureValue.getBytes();
PublicKey key = (PublicKey) publicKey.getNativeData(Constants.NATIVE_DATA_PUBLIC_KEY);
return CryptoUtils.verify("SHA384withECDSA", key, data, signature);
}
}

0 comments on commit 1f4311f

Please sign in to comment.