Skip to content

Commit

Permalink
feat: PrivateKeyUsagePeriod extension (pull request #15 from jeroentr…
Browse files Browse the repository at this point in the history
…appers)
  • Loading branch information
rbellens committed Nov 3, 2022
2 parents 63e5fc6 + 9708982 commit 27cc8f5
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
33 changes: 33 additions & 0 deletions lib/src/extension.dart
Expand Up @@ -93,6 +93,8 @@ abstract class ExtensionValue {
return BasicConstraints.fromAsn1(obj as ASN1Sequence);
case 37:
return ExtendedKeyUsage.fromAsn1(obj as ASN1Sequence);
case 16:
return PrivateKeyUsagePeriod.fromAsn1(obj as ASN1Sequence);
}
}
if (id.parent == peId) {
Expand Down Expand Up @@ -293,6 +295,37 @@ class ExtendedKeyUsage extends ExtensionValue {
String toString() => ids.join(', ');
}

class PrivateKeyUsagePeriod extends ExtensionValue {
final DateTime? notBefore;
final DateTime? notAfter;

PrivateKeyUsagePeriod({this.notBefore, this.notAfter});

/// Creates a basic constraints extension value from an [ASN1Sequence].
///
/// The ASN.1 definition is:
///
/// PrivateKeyUsagePeriod ::= SEQUENCE {
/// notBefore [0] GeneralizedTime OPTIONAL,
/// notAfter [1] GeneralizedTime OPTIONAL }
factory PrivateKeyUsagePeriod.fromAsn1(ASN1Sequence sequence) {
DateTime? notBefore;
DateTime? notAfter;
for (ASN1Object o in sequence.elements) {
var taggedObject = o;
if (taggedObject.tag == 128) {
notBefore = ASN1GeneralizedTime.fromBytes(o.encodedBytes).dateTimeValue;
} else if (taggedObject.tag == 129) {
notAfter = ASN1GeneralizedTime.fromBytes(o.encodedBytes).dateTimeValue;
}
}
return PrivateKeyUsagePeriod(notBefore: notBefore, notAfter: notAfter);
}

@override
String toString() => 'NotBefore:$notBefore, NotAfter:$notAfter';
}

/// The basic constraints extension identifies whether the subject of the
/// certificate is a CA and the maximum depth of valid certification paths
/// that include this certificate.
Expand Down
23 changes: 23 additions & 0 deletions test/x509_test.dart
Expand Up @@ -321,6 +321,29 @@ void main() {
expect(cert, isA<X509Certificate>());
}
});

test('parse privateKeyUsagePeriod', () {
var pem = '''-----BEGIN CERTIFICATE-----
MIIDJTCCAsygAwIBAgIIMWAojeoOOlkwCgYIKoZIzj0EAwIwgYYxFzAVBgNVBAMMDkNTQ0EgSGVhbHRoIE5MMQowCAYDVQQFEwEyMS0wKwYDVQQLDCRNaW5pc3RyeSBvZiBIZWFsdGggV2VsZmFyZSBhbmQgU3BvcnQxIzAhBgNVBAoMGktpbmdkb20gb2YgdGhlIE5ldGhlcmxhbmRzMQswCQYDVQQGEwJOTDAeFw0yMTA0MjYwODU3MzVaFw0zMjA0MjMwODU3MzVaMIGZMQswCQYDVQQGEwJOTDEjMCEGA1UECgwaS2luZ2RvbSBvZiB0aGUgTmV0aGVybGFuZHMxLTArBgNVBAsMJE1pbmlzdHJ5IG9mIEhlYWx0aCBXZWxmYXJlIGFuZCBTcG9ydDEKMAgGA1UEBRMBMTEqMCgGA1UEAwwhSGVhbHRoLURTQy12YWxpZC1mb3ItdmFjY2luYXRpb25zMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmcNCX0lhlqcvJ/YHl/+TDLbIO09nTsRUr7KP23Qp3KUXAcnq3EkrTVswaJx93exNhW3VeFdILS1vI84sWbJoW6OCAQ0wggEJMB8GA1UdIwQYMBaAFFak99WeVB9We0dQ33IDCu5uCzZlMBsGA1UdEgQUMBKkEDAOMQwwCgYDVQQHDANOTEQwGwYDVR0RBBQwEqQQMA4xDDAKBgNVBAcMA05MRDAXBgNVHSUEEDAOBgwrBgEEAQCON49lAQIwNwYDVR0fBDAwLjAsoCqgKIYmaHR0cDovL2NybC5ucGtkLm5sL0NSTHMvTkxELUhlYWx0aC5jcmwwHQYDVR0OBBYEFGzMKHGeML2Vkax4IVCKguaz0430MCsGA1UdEAQkMCKADzIwMjEwNDI2MDg1NzM1WoEPMjAyMTExMjIwODU3MzVaMA4GA1UdDwEB/wQEAwIHgDAKBggqhkjOPQQDAgNHADBEAiAZh9OiWVAJQbaJMhN3dWuDtnYrcbBAuXLX1Ma7mS1EvgIgVuD6aTsh8PIW0SunH8Tp00E2zMGQkbW1NHNIzrQmOKo=
-----END CERTIFICATE-----''';

var cert = parsePem(pem).single;

// openSSL result
// X509v3 Private Key Usage Period:
// Not Before: Apr 26 08:57:35 2021 GMT, Not After: Nov 22 08:57:35 2021 GMT

expect(cert, isA<X509Certificate>());

var c = cert as X509Certificate;
// get extension value
var pkup = c.tbsCertificate.extensions!
.map((e) => e.extnValue)
.whereType<PrivateKeyUsagePeriod>()
.first;
expect(pkup.notBefore, DateTime.parse('2021-04-26 08:57:35.000Z'));
expect(pkup.notAfter, DateTime.parse('2021-11-22 08:57:35.000Z'));
});
});

group('PolicyInformation', () {
Expand Down

0 comments on commit 27cc8f5

Please sign in to comment.