Skip to content

Commit

Permalink
Merge pull request #537 from Bhashinee/versionUpdate
Browse files Browse the repository at this point in the history
Introduce new APIs to sign and verify using SHA256withECDSA
  • Loading branch information
Bhashinee authored Dec 19, 2023
2 parents 3d4b29c + 33a0979 commit 4863cbd
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 0 deletions.
44 changes: 44 additions & 0 deletions ballerina/sign_verify.bal
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,26 @@ public isolated function signSha384withEcdsa(byte[] input, PrivateKey privateKey
'class: "io.ballerina.stdlib.crypto.nativeimpl.Sign"
} external;

# Returns the SHA256withECDSA 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:signSha256withEcdsa(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 signSha256withEcdsa(byte[] input, PrivateKey privateKey) returns byte[]|Error = @java:Method {
name: "signSha256withEcdsa",
'class: "io.ballerina.stdlib.crypto.nativeimpl.Sign"
} external;

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

# Verifies the SHA256withECDSA 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:signSha256withEcdsa(data, privateKey);
# crypto:PublicKey publicKey = check crypto:decodeEcPublicKeyFromTrustStore(keyStore, "keyAlias");
# boolean validity = check crypto:verifySha256withEcdsaSignature(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 verifySha256withEcdsaSignature(byte[] data, byte[] signature, PublicKey publicKey)
returns boolean|Error = @java:Method {
name: "verifySha256withEcdsaSignature",
'class: "io.ballerina.stdlib.crypto.nativeimpl.Sign"
} external;
13 changes: 13 additions & 0 deletions ballerina/tests/sign_verify_test.bal
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,19 @@ isolated function testVerifySha384withEcdsa() returns Error? {
test:assertTrue(check verifySha384withEcdsaSignature(payload, sha384withEcdsaSignature, publicKey));
}

@test:Config {}
isolated function testVerifySha256withEcdsa() 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[] sha256withEcdsaSignature = check signSha256withEcdsa(payload, privateKey);
test:assertTrue(check verifySha256withEcdsaSignature(payload, sha256withEcdsaSignature, publicKey));
}

@test:Config {}
isolated function testDecodeRsaPrivateKeyError() returns Error? {
KeyStore keyStore = {
Expand Down
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## [Unreleased]

### Added
- [Introduce new APIs to sign and verify using SHA256withECDSA](https://github.com/ballerina-platform/ballerina-library/issues/5889)

## [2.6.1] - 2023-12-12

### Added
- [Introduce new APIs to decode private and public keys from files](https://github.com/ballerina-platform/ballerina-library/issues/5871)

Expand Down
34 changes: 34 additions & 0 deletions docs/spec/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,15 @@ The conforming implementation of the specification is released and included in t
* 6.1.4. [RSA-SHA384](#614-rsa-sha384)
* 6.1.5. [RSA-SHA512](#615-rsa-sha512)
* 6.1.6. [SHA384withECDSA](#616-sha384withecdsa)
* 6.1.7. [SHA256withECDSA](#617-sha256withecdsa)
* 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)
* 6.2.7. [SHA256withECDSA](#627-sha256withecdsa)

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

Expand Down Expand Up @@ -534,6 +536,21 @@ crypto:PrivateKey privateKey = check crypto:decodeEcPrivateKeyFromKeyStore(keySt
byte[] signature = check crypto:signSha384withEcdsa(data, privateKey);
```

#### 6.1.7. [SHA256withECDSA](#617-sha256withecdsa)

This API can be used to create the SHA256withECDSA 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:signSha256withEcdsa(data, privateKey);
```

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

#### 6.2.1. [RSA-MD5](#621-rsa-md5)
Expand Down Expand Up @@ -637,3 +654,20 @@ byte[] signature = check crypto:signSha384withEcdsa(data, privateKey);
crypto:PublicKey publicKey = check crypto:decodeEcPublicKeyFromTrustStore(keyStore, "keyAlias");
boolean validity = check crypto:verifySha384withEcdsaSignature(data, signature, publicKey);
```

#### 6.2.7. [SHA256withECDSA](#627-sha256withecdsa)

This API can be used to verify the SHA256withECDSA 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:signSha256withEcdsa(data, privateKey);
crypto:PublicKey publicKey = check crypto:decodeEcPublicKeyFromTrustStore(keyStore, "keyAlias");
boolean validity = check crypto:verifySha256withEcdsaSignature(data, signature, publicKey);
```
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ public static Object signSha384withEcdsa(BArray inputValue, BMap<?, ?> privateKe
return CryptoUtils.sign("SHA384withECDSA", key, input);
}

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

public static Object signRsaSha512(BArray inputValue, BMap<?, ?> privateKey) {
byte[] input = inputValue.getBytes();
PrivateKey key = (PrivateKey) privateKey.getNativeData(Constants.NATIVE_DATA_PRIVATE_KEY);
Expand Down Expand Up @@ -117,4 +123,11 @@ public static Object verifySha384withEcdsaSignature(BArray dataValue, BArray sig
PublicKey key = (PublicKey) publicKey.getNativeData(Constants.NATIVE_DATA_PUBLIC_KEY);
return CryptoUtils.verify("SHA384withECDSA", key, data, signature);
}

public static Object verifySha256withEcdsaSignature(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("SHA256withECDSA", key, data, signature);
}
}

0 comments on commit 4863cbd

Please sign in to comment.