Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Ephenodrom committed Jul 7, 2020
1 parent b0d417b commit 25a24de
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 18 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ Uint8List rsaPublicKeyExponentToBytes(RSAPublicKey publicKey);
Uint8List rsaPrivateKeyToBytes(RSAPrivateKey privateKey);
ASN1Object encodeDN(Map<String, String> dn);
X509CertificateData x509CertificateFromPem(String pem);
AsymmetricKeyPair generateEcKeyPair();
String encodeEcPublicKeyToPem(ECPublicKey publicKey);
String encodeEcPrivateKeyToPem(ECPrivateKey ecPrivateKey);
String generateEccCsrPem(Map<String, String> attributes, ECPrivateKey privateKey, ECPublicKey publicKey);
```

### IterableUtils
Expand Down
50 changes: 38 additions & 12 deletions lib/src/X509Utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,18 +105,12 @@ class X509Utils {
}

///
/// Generates a [AsymmetricKeyPair] with the given [keySize].
/// Generates a elliptic curve [AsymmetricKeyPair] with the **prime256v1** algorithm.
///
static AsymmetricKeyPair generateEccKeyPair({int keySize = 256}) {
var keyParams = ECKeyGeneratorParameters(ECCurve_secp256r1());
static AsymmetricKeyPair generateEcKeyPair() {
var keyParams = ECKeyGeneratorParameters(ECCurve_prime256v1());

var secureRandom = FortunaRandom();
var random = Random.secure();
var seeds = <int>[];
for (var i = 0; i < 32; i++) {
seeds.add(random.nextInt(255));
}
secureRandom.seed(KeyParameter(Uint8List.fromList(seeds)));
var secureRandom = _getSecureRandom();

var rngParams = ParametersWithRandom(keyParams, secureRandom);
var k = ECKeyGenerator();
Expand Down Expand Up @@ -181,6 +175,8 @@ class X509Utils {
///
/// Generates a eliptic curve Certificate Signing Request with the given [attributes] using the given [privateKey] and [publicKey].
///
/// The CSR will be signed with algorithm **SHA-256/ECDSA**.
///
static String generateEccCsrPem(Map<String, String> attributes,
ECPrivateKey privateKey, ECPublicKey publicKey) {
ASN1ObjectIdentifier.registerFrequentNames();
Expand Down Expand Up @@ -213,7 +209,8 @@ class X509Utils {
}

static ECSignature eccSign(Uint8List inBytes, ECPrivateKey privateKey) {
var signer = ECDSASigner();
var signer = Signer('SHA-256/ECDSA');
//var signer = ECDSASigner();
var privParams = PrivateKeyParameter<ECPrivateKey>(privateKey);
var signParams = ParametersWithRandom(
privParams,
Expand Down Expand Up @@ -273,6 +270,15 @@ class X509Utils {
///
/// Enode the given elliptic curve [publicKey] to PEM format.
///
/// This is descripted in https://tools.ietf.org/html/rfc5480
///
/// ```ASN1
/// SubjectPublicKeyInfo ::= SEQUENCE {
/// algorithm AlgorithmIdentifier,
/// subjectPublicKey BIT STRING
/// }
/// ```
///
static String encodeEcPublicKeyToPem(ECPublicKey publicKey) {
ASN1ObjectIdentifier.registerFrequentNames();
var outer = ASN1Sequence();
Expand All @@ -298,18 +304,36 @@ class X509Utils {
/// ECPrivateKey ::= SEQUENCE {
/// version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
/// privateKey OCTET STRING
/// parameters [0] ECParameters {{ NamedCurve }} OPTIONAL
/// publicKey [1] BIT STRING OPTIONAL
/// }
///
/// ```
///
/// As descripted in the mentioned RFC, all optional values will always be set.
///
static String encodeEcPrivateKeyToPem(ECPrivateKey ecPrivateKey) {
ASN1ObjectIdentifier.registerFrequentNames();
var outer = ASN1Sequence();

var version = ASN1Integer(BigInt.from(1));
var privateKeyAsBytes = _bigIntToBytes(ecPrivateKey.d);
var privateKey = ASN1OctetString(privateKeyAsBytes);
var choice = ASN1Sequence(tag: 0xA0);

choice
.add(ASN1ObjectIdentifier.fromName(ecPrivateKey.parameters.domainName));

var publicKey = ASN1Sequence(tag: 0xA1);

var subjectPublicKey =
ASN1BitString(ecPrivateKey.parameters.G.getEncoded(false));
publicKey.add(subjectPublicKey);

outer.add(version);
outer.add(privateKey);
outer.add(choice);
outer.add(publicKey);
var dataBase64 = base64.encode(outer.encodedBytes);
var chunks = StringUtils.chunk(dataBase64, 64);

Expand Down Expand Up @@ -761,7 +785,9 @@ class X509Utils {
static ASN1Sequence _makeEccPublicKeyBlock(ECPublicKey publicKey) {
var algorithm = ASN1Sequence();
algorithm.add(ASN1ObjectIdentifier.fromName('ecPublicKey'));
algorithm.add(ASN1ObjectIdentifier.fromName('prime256v1'));
algorithm
.add(ASN1ObjectIdentifier.fromName(publicKey.parameters.domainName));

var subjectPublicKey = ASN1BitString(publicKey.Q.getEncoded(false));

var outer = ASN1Sequence();
Expand Down
9 changes: 3 additions & 6 deletions test/x509_utils_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -307,16 +307,15 @@ h9vE3e4Cq0OS3DA=
});

test('Test encodeECPublicKeyToPem', () {
var pair = X509Utils.generateEccKeyPair();
var pair = X509Utils.generateEcKeyPair();
var pem = X509Utils.encodeEcPublicKeyToPem(pair.publicKey);
expect(pem.startsWith('-----BEGIN EC PUBLIC KEY-----'), true);
expect(pem.endsWith('-----END EC PUBLIC KEY-----'), true);
});

test('Test encodeECPrivateKeyToPem', () {
var pair = X509Utils.generateEccKeyPair();
var pair = X509Utils.generateEcKeyPair();
var pem = X509Utils.encodeEcPrivateKeyToPem(pair.privateKey);
// TODO Check
expect(pem.startsWith('-----BEGIN EC PRIVATE KEY-----'), true);
expect(pem.endsWith('-----END EC PRIVATE KEY-----'), true);
});
Expand All @@ -343,7 +342,7 @@ h9vE3e4Cq0OS3DA=
});

test('Test generateEccCsrPem', () {
var pair = X509Utils.generateEccKeyPair();
var pair = X509Utils.generateEcKeyPair();
var dn = {
'CN': 'basic-utils.dev',
'O': 'Magic Company',
Expand All @@ -352,8 +351,6 @@ h9vE3e4Cq0OS3DA=
'C': 'DE',
};
var csr = X509Utils.generateEccCsrPem(dn, pair.privateKey, pair.publicKey);
print(csr);
// TODO The CSR is missing a NULL value in its AlgorithmIdentifier parameter.
var bytes = X509Utils.getBytesFromPEMString(csr);
var sequence = ASN1Sequence.fromBytes(bytes);
ASN1Sequence e1 = sequence.elements.elementAt(0);
Expand Down

0 comments on commit 25a24de

Please sign in to comment.