Giter VIP home page Giter VIP logo

dart-basic-utils's Introduction

Hi there ๐Ÿ‘‹

Support my work and consider checking out one of my apps!

SSL Toolkit

All-in-one crossplatform (Android/iOS/macOS/Windows) toolkit. It provides a comprehensive set of over 17 tools for individuals and organizations to perform various tasks related to SSL certificates.

Mockberry

Supercharge your API integration with effortless mocking, logging and on the fly data generation with Mockberry for macOS.

PowerSample Live

PowerSample Live is an easy-to-use crossplatform (Android/iOS/macOS/Windows) sampler to play different sounds in any situation.

Simple DNS

Simple and straightforward crossplatform (Android/iOS/macOS/Windows) tool for DNS lookup.

dart-basic-utils's People

Contributors

anas35 avatar arj-singh avatar arkare avatar asherbar avatar awhitford avatar beshr-eldebuch avatar ephenodrom avatar hatch01 avatar internetx-dl avatar kabaluyot avatar krille-chan avatar nikoo00o avatar ricardorb avatar romgrm avatar xceldeveloper avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dart-basic-utils's Issues

Pointycastle introduced in 2.7.0 threw exception on some certs

Before 2.7.0, these lines work:

File file = new File(cert.path); // e.g. on Android "/system/etc/security/cacerts/7892ad52.0" , the content of this file is pasted below
String certTxt = file.readAsStringSync();
List<int> certData = PemCodec(PemLabel.certificate).decode(certTxt);
String encoded = PemCodec(PemLabel.certificate).encode(certData);
X509CertificateData data = X509Utils.x509CertificateFromPem(encoded);
-----BEGIN CERTIFICATE-----
MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC
VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp
Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx
NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv
bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49
AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA
VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku
WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP
MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX
5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ
ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg
h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
-----END CERTIFICATE-----

After 2.7.0 (e.g. 2.7.1), X509CertificateData data = X509Utils.x509CertificateFromPem(encoded); will throw exception:

The following _TypeError was thrown building Consumer<CertsModel>(dirty, dependencies: 
type 'ASN1Sequence' is not a subtype of type 'ASN1Set'

Is there anything that the application should do when upgrading to the newer versions?

'State' name conflict.

In the last couple of days I have started seeing this error message appear in my IDE against Stateful widgets into which I import the basic_utils package. This is without having changed any dependencies:

The name 'State' is defined in the libraries 'package:flutter/src/widgets/framework.dart' and 'package:pointycastle/stream/chacha20poly1305.dart'.

This is not a serious issue as the simple workaround is to change the import statement from
import 'package:basic_utils/basic_utils.dart';
to eg.
import 'package:basic_utils/basic_utils.dart' as utils;

and then prefix all calls to the package methods with utils.

I just thought that I should make you aware of it.

I am using basic_utils: ^3.0.1 but it was occurring before I updated to the latest version.

flutter doctor -v output is:

[โˆš] Flutter (Channel stable, 2.0.4, on Microsoft Windows [Version 10.0.21354.1], locale en-ZA)
โ€ข Flutter version 2.0.4 at C:\flutter
โ€ข Framework revision b1395592de (8 days ago), 2021-04-01 14:25:01 -0700
โ€ข Engine revision 2dce47073a
โ€ข Dart version 2.12.2

[โˆš] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
โ€ข Android SDK at D:\Android
โ€ข Platform android-30, build-tools 30.0.3
โ€ข ANDROID_HOME = D:\Android
โ€ข ANDROID_SDK_ROOT = D:\Android
โ€ข Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
โ€ข Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
โ€ข All Android licenses accepted.

[โˆš] Chrome - develop for the web
โ€ข Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[โˆš] Android Studio (version 4.1.0)
โ€ข Android Studio at C:\Program Files\Android\Android Studio
โ€ข Flutter plugin can be installed from:
https://plugins.jetbrains.com/plugin/9212-flutter
โ€ข Dart plugin can be installed from:
https://plugins.jetbrains.com/plugin/6351-dart
โ€ข Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)

[โˆš] VS Code (version 1.55.1)
โ€ข VS Code at C:\Users\dicki\AppData\Local\Programs\Microsoft VS Code
โ€ข Flutter extension version 3.21.0

[โˆš] Connected device (3 available)
โ€ข sdk gphone x86 (mobile) โ€ข emulator-5554 โ€ข android-x86 โ€ข Android 11 (API 30) (emulator)
โ€ข Chrome (web) โ€ข chrome โ€ข web-javascript โ€ข Google Chrome 89.0.4389.114
โ€ข Edge (web) โ€ข edge โ€ข web-javascript โ€ข Microsoft Edge 89.0.774.68

โ€ข No issues found!

ECDSA Sign/Verifier

Hi, was testing out your library since one of it's dependency is PointyCastle.
Just would like to know if there is an ECDSA Sign/Verifier included in your CryptoUtils, or in another dart file?

Add php strtotime equivalent

Add strtotime equivalent that supports the following kind of strings:

  • now โœ”๏ธ
  • yesterday โœ”๏ธ
  • tomorrow โœ”๏ธ
  • +1 year 2 months 3 weeks โœ”๏ธ
  • -1 year 2 months 3 weeks โœ”๏ธ
  • 2 weeks ago โœ”๏ธ
  • last friday โœ”๏ธ
  • next friday / at 2 pm / 14:00:00 / hours 14 :heavy_check_mark:
  • 10 December 2018 โœ”๏ธ
  • 2 pm / am / next friday โœ”๏ธ
  • 04.37 pm / am / next day โœ”๏ธ
  • 9:05:42 pm / am / next day :heavy_check_mark:

help to decode generateRsaCsrPem with x509CertificateFromPem

Hi, Thank you for this library
i use X509Utils version ^2.6.2

i need to generate a certificate and keep public key on the certificate for share to other
i want to use certificate for sign, verifiy sign and key exchange
i wnat to give the certificate to customers (certificate with public key) i want to generate a qr code for sharing certificate
then when i sign a string and send for them, customers will find out if I signed it or not
or i want to use asymmetric encryption with certificate, i encrypt a string with certificate private key and send for customers and they can decrypt string with my certificate (if i give to them In the form of qr code)

i see the web, you examples, issues and you test but i cant decrypt pem certificate and find public key

i use this code

var dn = {
    'CN': 'basic-utils.dev',
    'O': 'Magic Company',
    'OU': 'org unit',
    'L': 'Fakecity',
    'S': 'FakeState',
    'C': 'DE',
};

keypair = CryptoUtils.generateRSAKeyPair();
var csr = X509Utils.generateRsaCsrPem(dn, keypair.privateKey, keypair.publicKey);

i generate certificate and check this on this link
https://www.sslchecker.com/csr/decode

i put the certificate for you

-----BEGIN CERTIFICATE REQUEST-----
MIICvjCCAaYCAQAweTEYMBYGA1UEAwwPYmFzaWMtdXRpbHMuZGV2MRYwFAYDVQQK
DA1NYWdpYyBDb21wYW55MREwDwYDVQQLDAhvcmcgdW5pdDERMA8GA1UEBwwIRmFr
ZWNpdHkxEjAQBgNVBAgMCUZha2VTdGF0ZTELMAkGA1UEBhMCREUwggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2s27seyvJHmW5d3VZK1D9RMeK6oNio5N4
OJCOGB5LsQbthSjuREDErUzqGRqepdlRu4jQJaAXDiuKjO1w4wDAkBwGP9Lk1Eb9
Sz1+BopddUIh8IY5T4goixHm8Ggw7lB3TTY5W2HbzMiu5SvZ4JyBokutaITHpMPw
pYk5Uj7W283wamLc5POQs6+jhQ3DvrqSzSI7+gki9p+S5SDURfBIySKHXM0HkPaV
8bg1111Tu1jmv/VU7D5R/WyIdk81FT4G/Wf+2a67iR2BbftX3zMC3SvwBb0BbfcU
Y9ijtEjvh47C5wQixetZs5oZfG6r1t4P3lxXquP+BkJhFI8db/I5AgMBAAGgADAN
BgkqhkiG9w0BAQsFAAOCAQEAfufnpVds2kPQpE6b/8RHDc63MIYWbT+etu65gFHo
M212hGJiC9pVvlNbnjOy7CEYC9jJ2jxRkovTd/A7BS7NUzyQeBY7IsML9AYCqBtm
ycnKEXG0Q3Np0Ght1Zia/CbUAOELlzmIpODzFaT0vJxFDDgGAF0By8P5AreP4jAb
12HmqXPv/HC4es4umbL9LazlobN81bsK8fRu48eENmpElllLmO+bRBbxSx4FiuYk
eoBKJIIrPLnPVm63JJOGHEzVYC/Cy35y+m2LSkgB8RD5mwGfXcNOSns2oXLnKgAp
RVHI7dZJODNWfajnENel1acyNOrzDfmZymklrSj8P7J5Tw==
-----END CERTIFICATE REQUEST-----

i try to decode certificate with this code

X509CertificateData data = X509Utils.x509CertificateFromPem(csr);

String commonName = data.subject["2.5.4.3"];
print(commonName);

but give me this error

E/flutter ( 8688): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: type 'ASN1Set' is not a subtype of type 'ASN1ObjectIdentifier' in type cast
E/flutter ( 8688): #0      X509Utils.x509CertificateFromPem (package:basic_utils/src/X509Utils.dart:245:53)

i use from this website and generate a certificate
https://www.samltool.com/self_signed_certs.php

when i use CSR thats give me error but when i use X.509 cert thats work very good
so i put X.509 cert for you

-----BEGIN CERTIFICATE-----
MIICfjCCAeegAwIBAgIBADANBgkqhkiG9w0BAQ0FADBcMQswCQYDVQQGEwJhZTEP
MA0GA1UECAwGVGVocmFuMQ8wDQYDVQQKDAZEYXJwb3UxDzANBgNVBAMMBk1vaHNl
bjEMMAoGA1UEBwwDZHNmMQwwCgYDVQQLDANzZGYwHhcNMjAwODE3MTUyNzAwWhcN
MjEwODE3MTUyNzAwWjBcMQswCQYDVQQGEwJhZTEPMA0GA1UECAwGVGVocmFuMQ8w
DQYDVQQKDAZEYXJwb3UxDzANBgNVBAMMBk1vaHNlbjEMMAoGA1UEBwwDZHNmMQww
CgYDVQQLDANzZGYwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMGlklLCqPWU
afjzaj5fpszDYSbrL0YJ+y4pwtMuFevReuk7amM+JVxw2nKlIhYaQH1KNPGNfbmK
P4kWMeaXdRxsS6W4mu75TFGXhlufiIO1U75d5T/rLx72AXZGqzBfEGoaaR7LnPRJ
parv5m2R1E0N77ZbrVtxzSeSH6sh3B/3AgMBAAGjUDBOMB0GA1UdDgQWBBSXSqGK
ux8IE5m4NSriAEU9f35KuTAfBgNVHSMEGDAWgBSXSqGKux8IE5m4NSriAEU9f35K
uTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4GBAKxX53UR2zUjhO4RWdG6
VJSFN462GixNVuMLNCUsHP+2an69xbS3uiFlZajhhjR51dWHo93kKfR/37afTtN4
UbevBk4LgAIS0CLXDTFQkzxQJDLUHTLBwQWtxFDHFc3TcBJmp5tUl5BsZASahVwS
NlYU3RWImVRogRKX9wt5WRt4
-----END CERTIFICATE-----

i dont know what is the problem but i need to generate a certificate Just like the top X.509 cert certificate
if you know a package for generate this type please say to me
if toy can help me to generate this certificate i will be very grateful
please help me for solved the problem
thank you

String Capitalize Problem

Hello guys,

Thank you for this helpful Utils. There is a bug in capitalize operation in StringUtils.

It is unable to capitalize the sentence with space at the beginning or at the end and throwing exception. The source code is

static String capitalize(String s, {bool allWords = false}) {
    if (allWords) {
      var words = s.split(' ');
      var capitalized = [];
      for (var w in words) {
        capitalized.add(capitalize(w));
      }
      return capitalized.join(' ');
    } else {
      return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
    }
  }

for example; when you push '( CAFE ) ' with space at the end, we have an exception like

-->> RangeError (end): Invalid value: Only valid value is 0: 1

I just change the code as below

static String capitalize(String s, {bool allWords = false}) {
    if (s == null || s.length == 0) return '';
    s = s.trim();

    if (allWords) {
      var words = s.split(' ');
      var capitalized = [];
      for (var w in words) {
        capitalized.add(capitalize(w));
      }
      return capitalized.join(' ');
    } else {
      return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
    }
  }

and that fixed the problem for me. It would be great if you fixed the code on your side with a more proper solution.

Thanks.

Error: The argument type 'String' can't be assigned to the parameter type 'Uri'.

image

/C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/basic_utils-2.7.1/lib/src/HttpUtils.dart:24:37: Error: The argument type 'String' can't be assigned to the parameter type 'Uri'.

  • 'Uri' is from 'dart:core'.
    var response = await client.get(finalUrl, headers: headers);
    ^
    /C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/basic_utils-2.7.1/lib/src/HttpUtils.dart:81:38: Error: The argument type 'String' can't be assigned to the parameter type 'Uri'.

  • 'Uri' is from 'dart:core'.
    var response = await client.post(finalUrl, body: body, headers: headers);
    ^
    /C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/basic_utils-2.7.1/lib/src/HttpUtils.dart:144:37: Error: The argument type 'String' can't be assigned to the parameter type 'Uri'.

  • 'Uri' is from 'dart:core'.
    var response = await client.put(finalUrl, body: body, headers: headers);
    ^
    /C:/src/flutter/.pub-cache/hosted/pub.dartlang.org/basic_utils-2.7.1/lib/src/HttpUtils.dart:203:40: Error: The argument type 'String' can't be assigned to the parameter type 'Uri'.

  • 'Uri' is from 'dart:core'.
    var response = await client.delete(finalUrl, headers: headers);

    error after flutter run
    to fix parse finalUrl to Uri

CryptoUtils.rsaPrivateKeyExponentToBytes missing ?

Hi,
I need to store a private-key as a byte array (modulus and exponent).
I can save modulus by CryptoUtils.rsaPrivateKeyModulusToBytes but no CryptoUtils.rsaPrivateKeyExponentToBytes is found.

Is CryptoUtils.rsaPrivateKeyExponentToBytes missing ? And the ....FromBytes related functions ?
How can I save private-key exponent along with private-key modulus to have the whole key stored and then, reloaded ?

Thanks,
Marco

How to request extensions in generateRsaCsrPem

Hi.

I am trying to include codesigning extensions in my CSR using generateRsaCsrPem. I've read through the code and previous issues and it isn't obvious how I would do it.

Many thanks!

The following ASN1Exception object was thrown building Instance of 'ASN1Exception'

When I was decoding this certificate, I ran into the error below:

[+6401 ms] I/flutter (17765): โ•โ•โ•ก EXCEPTION CAUGHT BY WIDGETS LIBRARY โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
[        ] I/flutter (17765): The following ASN1Exception object was thrown building:
[        ] I/flutter (17765):   Instance of 'ASN1Exception'
[        ] I/flutter (17765): 
[        ] I/flutter (17765): When the exception was thrown, this was the stack:
[        ] I/flutter (17765): #0      ASN1Parser._doPrimitive (package:asn1lib/asn1parser.dart:109:9)
[        ] I/flutter (17765): #1      ASN1Parser.nextObject (package:asn1lib/asn1parser.dart:51:13)
[        ] I/flutter (17765): #2      ASN1Sequence._decodeSeq (package:asn1lib/asn1sequence.dart:73:27)
[        ] I/flutter (17765): #3      new ASN1Sequence.fromBytes (package:asn1lib/asn1sequence.dart:23:5)
[        ] I/flutter (17765): #4      ASN1Parser._doPrimitive (package:asn1lib/asn1parser.dart:72:29)
[        ] I/flutter (17765): #5      ASN1Parser.nextObject (package:asn1lib/asn1parser.dart:51:13)
[        ] I/flutter (17765): #6      ASN1Sequence._decodeSeq (package:asn1lib/asn1sequence.dart:73:27)
[        ] I/flutter (17765): #7      new ASN1Sequence.fromBytes (package:asn1lib/asn1sequence.dart:23:5)
[        ] I/flutter (17765): #8      ASN1Parser._doPrimitive (package:asn1lib/asn1parser.dart:72:29)
[        ] I/flutter (17765): #9      ASN1Parser.nextObject (package:asn1lib/asn1parser.dart:51:13)
[        ] I/flutter (17765): #10     ASN1Sequence._decodeSeq (package:asn1lib/asn1sequence.dart:73:27)
[        ] I/flutter (17765): #11     new ASN1Sequence.fromBytes (package:asn1lib/asn1sequence.dart:23:5)
[        ] I/flutter (17765): #12     ASN1Parser._doPrimitive (package:asn1lib/asn1parser.dart:72:29)
[        ] I/flutter (17765): #13     ASN1Parser.nextObject (package:asn1lib/asn1parser.dart:51:13)
[        ] I/flutter (17765): #14     X509Utils.x509CertificateFromPem (package:basic_utils/src/X509Utils.dart:260:34)

The PEM string is below:

-----BEGIN CERTIFICATE-----
MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1
MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1
czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG
CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy
MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl
ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS
b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy
euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO
bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw
WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d
MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE
1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD
VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/
zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB
BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF
BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV
v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG
E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW
iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v
GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0=
-----END CERTIFICATE-----

The data in text format is:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            54:80:f9:a0:73:ed:3f:00:4c:ca:89:d8:e3:71:e6:4a
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=EE, O=AS Sertifitseerimiskeskus, CN=EE Certification Centre Root CA/[email protected]
        Validity
            Not Before: Oct 30 10:10:30 2010 GMT
            Not After : Dec 17 23:59:59 2030 GMT
        Subject: C=EE, O=AS Sertifitseerimiskeskus, CN=EE Certification Centre Root CA/[email protected]
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c8:20:c0:ec:e0:c5:4b:ab:07:78:95:f3:44:ee:
                    fb:0b:0c:ff:74:8e:61:bb:b1:62:ea:23:d8:ab:a1:
                    65:32:7a:eb:8e:17:4f:96:d8:0a:7b:91:a2:63:6c:
                    c7:8c:4c:2e:79:bf:a9:05:fc:69:5c:95:8d:62:f9:
                    b9:70:ed:c3:51:7d:d0:93:e6:6c:eb:30:4b:e1:bc:
                    7d:bf:52:9b:ce:6e:7b:65:f2:38:b1:c0:a2:32:ef:
                    62:b2:68:e0:61:53:c1:36:95:ff:ec:94:ba:36:ae:
                    9c:1c:a7:32:0f:e5:7c:b4:c6:6f:74:fd:7b:18:e8:
                    ac:57:ed:06:20:4b:32:30:58:5b:fd:cd:a8:e6:a1:
                    fc:70:bc:8e:92:73:db:97:a7:7c:21:ae:3d:c1:f5:
                    48:87:6c:27:bd:9f:25:74:81:55:b0:f7:75:f6:3d:
                    a4:64:6b:d6:4f:e7:ce:40:ad:0f:dd:32:d3:bc:8a:
                    12:53:98:c9:89:fb:10:1d:4d:7e:cd:7e:1f:56:0d:
                    21:70:85:f6:20:83:1f:f6:ba:1f:04:8f:ea:77:88:
                    35:c4:ff:ea:4e:a1:8b:4d:3f:63:1b:44:c3:44:d4:
                    25:76:ca:b7:8d:d7:1e:4a:66:64:cd:5c:c5:9c:83:
                    e1:c2:08:88:9a:ec:4e:a3:f1:3e:1c:2c:d9:6c:1d:
                    a1:4b
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Subject Key Identifier: 
                12:F2:5A:3E:EA:56:1C:BF:CD:06:AC:F1:F1:25:C9:A9:4B:D4:14:99
            X509v3 Extended Key Usage: 
                TLS Web Client Authentication, TLS Web Server Authentication, Code Signing, E-mail Protection, Time Stamping, OCSP Signing
    Signature Algorithm: sha1WithRSAEncryption
         7b:f6:e4:c0:0d:aa:19:47:b7:4d:57:a3:fe:ad:bb:b1:6a:d5:
         0f:9e:db:e4:63:c5:8e:a1:50:56:93:96:b8:38:c0:24:22:66:
         bc:53:14:61:95:bf:d0:c7:2a:96:39:3f:7d:28:b3:10:40:21:
         6a:c4:af:b0:52:77:18:e1:96:d8:56:5d:e3:dd:36:5e:1d:a7:
         50:54:a0:c5:2a:e4:aa:8c:94:8a:4f:9d:35:ff:76:a4:06:13:
         91:a2:a2:7d:00:44:3f:55:d3:82:3c:1a:d5:5b:bc:56:4c:22:
         2e:46:43:8a:24:40:2d:f3:12:b8:3b:70:1a:a4:96:b9:1a:af:
         87:41:1a:6a:18:0d:06:4f:c7:3e:6e:b9:29:4d:0d:49:89:11:
         87:32:5b:e6:4b:04:c8:e4:5c:e6:74:73:94:5d:16:98:13:95:
         fe:fb:db:b1:44:e5:3a:70:ac:37:6b:e6:b3:33:72:28:c9:b3:
         57:a0:f6:02:16:88:06:0b:b6:a6:4b:20:28:d4:de:3d:8b:ad:
         37:05:53:74:fe:6e:cc:bc:43:17:71:5e:f9:c5:cc:1a:a9:61:
         ee:f7:76:0c:f3:72:f4:72:ad:cf:72:02:36:07:47:cf:ef:19:
         50:89:60:cc:e9:24:95:0f:c2:cb:1d:f2:6f:76:90:c7:cc:75:
         c1:96:c5:9d
SHA1 Fingerprint=C9:A8:B9:E7:55:80:5E:58:E3:53:77:A7:25:EB:AF:C3:7B:27:CC:D7

ASN.1 JavaScript decoder of this certificate is at
http://lapo.it/asn1js/#MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0-W2Ap7kaJjbMeMTC55v6kF_GlclY1i-blw7cNRfdCT5mzrMEvhvH2_UpvObntl8jixwKIy72KyaOBhU8E2lf_slLo2rpwcpzIP5Xy0xm90_XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ_dMtO8ihJTmMmJ-xAdTX7Nfh9WDSFwhfYggx_2uh8Ej-p3iDXE_-pOoYtNP2MbRMNE1CV2yreN1x5KZmTNXMWcg-HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0TAQH_BAUwAwEB_zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy_zQas8fElyalL1BSZMEUGA1UdJQQ-MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo_6tu7Fq1Q-e2-RjxY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX_dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5uuSlNDUmJEYcyW-ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU3j2LrTcFU3T-bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8_vGVCJYMzpJJUPwssd8m92kMfMdcGWxZ0

Add cert sha256Thumbprint support

We have sha256Thumbprint support on SPKI field in #12 , but we don't have sha256Thumbprint on the whole cert. Browsers use sha256Thumbprint of the whole cert, e.g. Apple lists the sha256 fingerprints here https://support.apple.com/en-us/HT210770

On the other hand, I see sha1Thumbprint is available on the whole cert, but the format isn't same as browser display, see screenshot below:

image

It seems the space characters was stripped out in X509CertificateData.sha1Thumbprint

Capitalize each word

Thanks for the useful plugin!

Browsing the docs, I can see capitalize that does the quick lazy fox -> The quick lazy fox, but is there a function that does the quick lazy fox -> The Quick Lazy Fox ?

".." crash

Thank you for the fast fix with the last issue!

Unfortunately, I've found another edge-case

The method 'contains' was called on null.
flutter: Receiver: null
flutter: Tried calling: contains("")

at

 When the exception was thrown, this was the stack:
flutter: #0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
flutter: #1      DomainUtils.isSubTld (package:basic_utils/src/DomainUtils.dart:30:17)
flutter: #2      DomainUtils.isSubDomain (package:basic_utils/src/DomainUtils.dart:55:17)
flutter: #3      DomainUtils.isDomainName (package:basic_utils/src/DomainUtils.dart:18:31)

for the input ".." (just two consecutive dots)

Thanks

Tag 164 is not supported yet for X509Util in read Certificate Signing Request (CSR)

hi every one.
I need help when I try get Certificate from CSR file .
the contain of csr file is :
var x509Pem ='''-----BEGIN CERTIFICATE REQUEST-----
MIIB7TCCAZMCAQAwXzELMAkGA1UEBhMCU0ExEzARBgNVBAsMCjMxMjM0NTY3ODkx
EzARBgNVBAoMCjMxMjM0NTY3ODkxJjAkBgNVBAMMHVRTVC04ODY0MzExNDUtMzEy
MzQ1Njc4OTAwMDAzMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEkNOiV8GaCBVDnQw2
bM1Wy6PqIRZ6t+/hxJNQxg7FAdWK0PcUiUdv5ry2SVyFSz/qY34IJuPstO01fLWv
c41ny6CB1DCB0QYJKoZIhvcNAQkOMYHDMIHAMCEGCSsGAQQBgjcUAgQUDBJaQVRD
QS1Db2RlLVNpZ25pbmcwgZoGA1UdEQSBkjCBj6SBjDCBiTE7MDkGA1UEBAwyMS1U
U1R8Mi1UU1R8My1lZDIyZjFkOC1lNmEyLTExMTgtOWI1OC1kOWE4ZjExZTQ0NWYx
HzAdBgoJkiaJk/IsZAEBDA8zMTIzNDU2Nzg5MDAwMDMxDTALBgNVBAwMBDExMTEx
DDAKBgNVBBoMA1RTVDEMMAoGA1UEDwwDVFNUMAoGCCqGSM49BAMCA0gAMEUCIQCJ
bnRkFWRGFymr/HW84klYXSoxQLe8yuhewNOD86OdKQIgEeuUUbMzr2C5VGTKAOFo
ia4a0ZuZLVXe3JGRUtmvLZk=
-----END CERTIFICATE REQUEST-----''';

CertificateSigningRequestData data = X509Utils.csrFromPem(x509Pem);

the error is Tag 164 is not supported yet

thanks and best regards.

CSR - SAN adds "DNS" for no reason?

Hi,

when adding email to SAN attributes, ex:

X509Utils.generateEccCsrPem(x509subject,
keyPair.privateKey as ECPrivateKey, keyPair.publicKey as ECPublicKey,
san: List.of(
["email:tiago.santos@********"]));

It seems to add "DNS before", see screenshot below
Screenshot 2021-10-27 at 10 34 14

Do you know why this 'DNS' is being show? The expected behavior is:

Screenshot 2021-10-27 at 10 31 44

hexToInt and intToHex

hexToInt

///
/// Converts the given [hex] color string to the corresponding int
///
static int hexToInt(String hex) {
if (hex.startsWith('#')) {
hex = hex.replaceFirst('#', 'FF');
return int.parse(hex, radix: 16);
} else {
if (hex.length == 6) {
hex = 'FF' + hex;
}
return int.parse(hex, radix: 16);
}
}

What do you think should happen with these test cases?

    expect(ColorUtils.hexToInt('000001'), 0xFF000001);
    expect(ColorUtils.hexToInt('00000002'), 0x00000002);
    expect(ColorUtils.hexToInt('3'), 0x00000003);
    expect(ColorUtils.hexToInt('#4'), 0xFF000004);

The last one fails -- it returns 0xFF4 instead of 0xFF000004.

The code seems to be unclear about its assumptions. If a Hex Color Code should always be 6 or 8 characters, then the function should either assert that, or check that.

I'm guessing that you supply an FF opacity when no alpha is provided. That's fine, but then presumably any value less than 6 digits should be treated as having preceding zeros.

intToHex

///
/// Converts the given integer [i] to a hex string with a leading #.
///
static String intToHex(int i) {
var s = i.toRadixString(16);
if (s.length == 8) {
return '#' + s.substring(2).toUpperCase();
} else {
return '#' + s.toUpperCase();
}
}

What do you think should happen with these test cases?

    expect(ColorUtils.intToHex(0xFF0000FA), '#0000FA');
    expect(ColorUtils.intToHex(0x100000FB), '#0000FB');
    expect(ColorUtils.intToHex(0x000000FC), '#0000FC');

The last one fails -- it returns "#FC" instead of "#0000FC".

The intToHex function is stripping the alpha/opacity, so a AARRGGBB hex code will turn into #RRGGBB.

Generally, one would assume that i == hexToInt(intToHex(i)), but if there is a non FF alpha value, then that is not true.

Dart Basic Utils real life usage examples

As far as I can see, this package seems to be used quite often. If you use this package in one of your projects, feel free to mention the project in this issue. If we get a nice list of real life usage examples, I will create a list and display it on this repository ( README and/or seperate file ).

Some Infos that would be nice to have :

  • Projekt name
  • Link ( to Github / App store / website )
  • Which Utils do you use

Provide a SPKI field

Comparing the hash of a certificate SubjectPublicKeyInfo is the best practice to tell if two certs have the same key, more information on https://www.imperialviolet.org/2011/05/04/pinning.html .

Can we please add a field SPKI, so something like hash(data.subject['SPKI']) can easily offer user/developer the capability to compare keys if they need to.

isDigit exception on empty string

Hey :)

Thanks for the great package!

I found a tiny bug

 ///
  /// Checks if the given string [s] is a digit
  ///
  static bool isDigit(String s) {
    if (s.length > 1) {
      for (int r in s.runes) {
        if (r ^ 0x30 > 9) {
          return false;
        }
      }
      return true;
    } else {
      return s.runes.first ^ 0x30 <= 9; /// Here
    }
  }

You're taking the first element of the runes from an empty String which leads to an exception.

Many statics should be const

Consider the following code:

class DateUtils {
  static int daysOfWeek = 7;
}  
  
main() {
  print("Hello, World!");
  print("DateUtils.daysOfWeek: ${DateUtils.daysOfWeek}");
  DateUtils.daysOfWeek = 8;
  print("DateUtils.daysOfWeek: ${DateUtils.daysOfWeek}");
}

It should be illegal to override the DateUtils.daysOfWeek. If this was declared as a const, the code would fail to compile (as it should).

Invalid pem generated for ECDSA pair

Hi, I am using your lib to implement crypto functions in my project, ECDSA key pair for secp256k1 curve.

AsymmetricKeyPair asymmetricKeyPair = CryptoUtils.generateEcKeyPair(curve: 'secp256k1');
ECPrivateKey ecPrivateKey = asymmetricKeyPair.privateKey as ECPrivateKey;
String ecPrivateKeyPem = CryptoUtils.encodeEcPrivateKeyToPem(ecPrivateKey);

But generated pem string is not correct, when I try to import it with php or nodejs code.

I checked code and found this part confusing:

stringValues: ecPrivateKey.parameters!.G.getEncoded(false));

I think this is wrong because here is encoding of curve parameters, I think there need to be publicKey points x, y.

  ECPoint G = ecPrivateKey.parameters!.G;
  ECPoint? Q = G * ecPrivateKey.d;

But that is not all. I am beginner in Dart, so I can not easy understand code. I think there are also some errors in further encoding of pem, and also added padding ASN1BitString.

Because there is no any other alternative for this, I will try my best to find out and help in solving this issue.

The getter 'name' isn't defined for the class 'Enum'.

Cannot build empty flutter project with dependency basic_utils: ^4.0.1

Error: The getter 'name' isn't defined for the class 'Enum'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'name'.
: element.name == enumName,
^^^^

The source code from EnumUtils:

static T getEnum<T extends Enum>(
      final String enumName, final List<T> enumList, final T defaultEnum,
      {bool ignoreCase = false}) {
    return enumList.firstWhere(
      (element) => ignoreCase
          ? element.name.toUpperCase() == enumName.toUpperCase()
          : element.name == enumName,
      orElse: () => defaultEnum,
    );
  }  

Indeed, the class Enum does not contain the field "name".
Source code for Enum:

@Since("2.14")
abstract class Enum {
  int get index;
}

Have I missed some things?

Fails to build for web

The pointycastle dependency

pointycastle: ^3.1.3

is causing the build for web to fail.

see:

bcgit/pc-dart#112

Please either revert to 3.1.1 or update to 3.2.0 once it is released.

UPDATE

As a work around, I found pointycastle 3.1.2 compiled to web, so pegging the version in the pubspec worked:

  basic_utils: 3.3.2
  pointycastle: 3.1.2

X509Utils crash when cert has no CN but a SAN

I am checking certificates to see if the SAN/CN matches what I am expecting and everything works just fine until I started using certificates from BUYPASS.COM.

I use the same code with a LetsEncrypt and or a ZeroSSL cert and everything works as expected, I guess because they both include a CN/Subject.. Interestingly everything work fine also with a cert with a CN/Subject and SAN.. Example cert for that below also from stackoverflow..

Being a European CA they give out certificates without a CN but with a SAN and that causes a failure..

Unhandled exception:
type 'ASN1Boolean' is not a subtype of type 'ASN1OctetString' in type cast
#0 X509Utils._fetchSansFromExtension (package:basic_utils/src/X509Utils.dart:504:25)
#1 X509Utils.x509CertificateFromPem. (package:basic_utils/src/X509Utils.dart:368:18)
#2 List.forEach (dart:core-patch/growable_array.dart:282:8)
#3 X509Utils.x509CertificateFromPem (package:basic_utils/src/X509Utils.dart:364:28)
#4 main (file:///C:/Users/colin/Github/certcheck/bin/certcheck.dart:8:24)
#5 _startIsolate. (dart:isolate-patch/isolate_patch.dart:299:32)
#6 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

Process finished with exit code 255

Small bit of sample code
import 'dart:io';

import 'package:basic_utils/basic_utils.dart';

void main(List arguments) {
var x509Pem = new File('testlab.pem').readAsStringSync();
var data = X509Utils.x509CertificateFromPem(x509Pem);
var subjectAlternativeName = data.subjectAlternativNames;
print("SAN: ${subjectAlternativeName}");
var commonName = data.subject["2.5.4.3"];
print("CN: ${commonName}");
print("---------------");
}

and a test.lab.shaduf.com cert to test with..

-----BEGIN CERTIFICATE-----
MIIGQzCCBCugAwIBAgIKWNF1YknimMXcJzANBgkqhkiG9w0BAQsFADBLMQswCQYD
VQQGEwJOTzEdMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMM
FEJ1eXBhc3MgQ2xhc3MgMiBDQSA1MB4XDTIwMDkzMDAzMTg1N1oXDTIxMDMyOTIx
NTkwMFowADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMdi82GXyrIB
6syElYZjAcDsovgVi75Ha+BQEfFNZEk7gx9hKJjKqtS4ml+I/jeYkkBZJKkRZ/QB
kDxP+C3katM3QhZ1Ro/uJDh7lx60+S2W3By+rVJdR0JKs1kxalq/fkC/rMSCPRSr
Sb7DakuQNDytqMvwI3Be60L5UIt+vzITKS+zXru/DsK75I0DmObKzvWVyPdI3KRX
NpJfHYqAdN3AQIlftqrwuOwjPCVfSfmpQ/kWSBPnLMX4JJjNTrpR+bO8Zeh6AcnV
ZrmF9nflYC4LE8P/WPY4l6+3MXhmZLI6cFRKjHrb+TsqJqU6RUZ7Kdcy0whf9Plq
lWdhP3BaAfcCAwEAAaOCAnIwggJuMAkGA1UdEwQCMAAwHwYDVR0jBBgwFoAUJ1Kk
by0qq0CTkOzWacv+fGE7fEIwHQYDVR0OBBYEFCeb0lXIYklGgxzvQrx7jEuWGfOW
MA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw
HwYDVR0gBBgwFjAKBghghEIBGgECBzAIBgZngQwBAgEwOgYDVR0fBDMwMTAvoC2g
K4YpaHR0cDovL2NybC5idXlwYXNzLm5vL2NybC9CUENsYXNzMkNBNS5jcmwwIQYD
VR0RAQH/BBcwFYITdGVzdC5sYWIuc2hhZHVmLmNvbTBqBggrBgEFBQcBAQReMFww
IwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmJ1eXBhc3MuY29tMDUGCCsGAQUFBzAC
hilodHRwOi8vY3J0LmJ1eXBhc3Mubm8vY3J0L0JQQ2xhc3MyQ0E1LmNlcjCCAQQG
CisGAQQB1nkCBAIEgfUEgfIA8AB1APZclC/RdzAiFFQYCDCUVo7jTRMZM7/fDC8g
C8xO8WTjAAABdN0FN7EAAAQDAEYwRAIgArAvLNqvUrMg/vDQu8zNgsoGahFodt2O
faPW/w07BZICIHek8n/zq1lbW58XForWdbXZ6ogqd5YgaVNS5Gy6jukYAHcARJRl
LrDuzq/EQAfYqP4owNrmgr7YyzG1P9MzlrW2gagAAAF03QUv+wAABAMASDBGAiEA
14996HrGYMCydAXZDFOUF3yt2V26IEb3lfLY3nPmTzMCIQC6Fto0DF97qpHgCAaf
YS2MFKbiTYN+HTv5+nDcoE886TANBgkqhkiG9w0BAQsFAAOCAgEAqZigbgUbLZse
PAUc+SDyPu456PoGHFTF7qUgOPJd5roARLcpiI8zxr8zSIirrlzfdUgRozdzGL7Y
hJ3XtNlg5F/WDQHWC6XeJSXyLzlnaqnvEckkHrvW2PfX+JsdgaIue9/mjZfqe1nk
/jJwK2ftw40l4sfxIpmNP3zjCzg0jMnakmzDf3cRg2r78VyzeqONr1SHyAaLvFmr
F6ZU5mCrxKO3JjMLGkJw1Rxc16fqGNniKPoqmEZbliJgSNLBK23MuRHpWvCG6JMT
AE0a9lkAdUQ07NJRJaBpEus1wYkPyO2b4Di69On2kdUsQ9LdU5aAIB9RCj5z97GQ
UN7LqL8NWQgKio8MgclLmP9s+IdWnB/cGPMrO6xyqBWtKA6rE0BCQTqYKOODPTXU
sR6+GN+bgkxtVxdKt52aWo6gy6Xuq98TXOj17m9hfKMIBRitrDJgU0v5YY5BLGYi
DpKZ45oA1K/PMZba/ZxxS9CzMU803ouHZZUJQgbJIaRUxVf0YrVKfcDdhEJ6MrRg
04mwh3NteH1/O3uQ+mFtKsmj1rFt9WMzgsO15fcYiCjjSzui/1jJL+15epiWXSFd
aTMXqalErmW7yZZ4+xHVFPcR+Wt/aXcJ9QaTf+N5sPwIYuQT5k3ZsA6z0bO/FV7i
8UhhGUUcPT6NuTN1LY7k+wvsdcRayEU=
-----END CERTIFICATE-----

And the StackOverflow cert with CN and SAN

-----BEGIN CERTIFICATE-----
MIIHJTCCBg2gAwIBAgISA72+1m+qM4K1gtDMN1jR2FJbMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMzAeFw0yMDA4MDcxMzAxMDBaFw0y
MDExMDUxMzAxMDBaMB4xHDAaBgNVBAMMEyouc3RhY2tleGNoYW5nZS5jb20wggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQChAaaXCGRfHl8uAuVzaQIAsNWj
sz679b63jJSb8HQOi4ZIc7puQXNZ78L/QrKeomO3+CsR4vd4k7RAITzmsyP3Xnz+
hrgbkG2iFGfN6APhnfC3jaSNsDk/zcy1EKzpuUVYOp+fpqqJuYvXP4eG3o8Gmeln
rweONZWyA2KxQYyiNNbnwdSpSASDbObhtDgXDS8g8fiFtZvjxaSrAPydx/L7AbYG
jyslc4Boo+JoXl4/teVWLQkKMHXEiDzaaOec/LFqyh2dGmlZs+EDis77I1qRegA8
x/Z/HvhUyagjXB9eqqpiaMR5WkVXRcAoSPa1kM+VcXRyZh+XN3nvB0Pbenc/AgMB
AAGjggQvMIIEKzAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBtuDXxB32488D9N/baT
nSOcs9BtMB8GA1UdIwQYMBaAFKhKamMEfd265tE5t6ZFZe/zqOyhMG8GCCsGAQUF
BwEBBGMwYTAuBggrBgEFBQcwAYYiaHR0cDovL29jc3AuaW50LXgzLmxldHNlbmNy
eXB0Lm9yZzAvBggrBgEFBQcwAoYjaHR0cDovL2NlcnQuaW50LXgzLmxldHNlbmNy
eXB0Lm9yZy8wggHkBgNVHREEggHbMIIB14IPKi5hc2t1YnVudHUuY29tghIqLmJs
b2dvdmVyZmxvdy5jb22CEioubWF0aG92ZXJmbG93Lm5ldIIYKi5tZXRhLnN0YWNr
ZXhjaGFuZ2UuY29tghgqLm1ldGEuc3RhY2tvdmVyZmxvdy5jb22CESouc2VydmVy
ZmF1bHQuY29tgg0qLnNzdGF0aWMubmV0ghMqLnN0YWNrZXhjaGFuZ2UuY29tghMq
LnN0YWNrb3ZlcmZsb3cuY29tghUqLnN0YWNrb3ZlcmZsb3cuZW1haWyCDyouc3Vw
ZXJ1c2VyLmNvbYINYXNrdWJ1bnR1LmNvbYIQYmxvZ292ZXJmbG93LmNvbYIQbWF0
aG92ZXJmbG93Lm5ldIIUb3BlbmlkLnN0YWNrYXV0aC5jb22CD3NlcnZlcmZhdWx0
LmNvbYILc3N0YXRpYy5uZXSCDXN0YWNrYXBwcy5jb22CDXN0YWNrYXV0aC5jb22C
EXN0YWNrZXhjaGFuZ2UuY29tghJzdGFja292ZXJmbG93LmJsb2eCEXN0YWNrb3Zl
cmZsb3cuY29tghNzdGFja292ZXJmbG93LmVtYWlsghFzdGFja3NuaXBwZXRzLm5l
dIINc3VwZXJ1c2VyLmNvbTBMBgNVHSAERTBDMAgGBmeBDAECATA3BgsrBgEEAYLf
EwEBATAoMCYGCCsGAQUFBwIBFhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCC
AQMGCisGAQQB1nkCBAIEgfQEgfEA7wB1AOcS8rA3fhpi+47JDGGE8ep7N8tWHREm
W/Pg80vyQVRuAAABc8k5k1sAAAQDAEYwRAIgaSN4+Dp0Ok5hMAHQfloLqMw0AHS5
g/qCdCkjDXTIZZkCICauC3SqsvYGYfMD0MFJIwcKVZ0LyyeFmi84MfLLQ0v1AHYA
sh4FzIuizYogTodm+Su5iiUgZ2va+nDnsklTLe+LkF4AAAFzyTmTTAAABAMARzBF
AiAlqHGi3QFuPFuKjh1M9PHK83/e2P1RUBElKWcFMj1KPAIhAP/7SHtOGAGXJ9lu
cw35Pa+O1DB2knhkQvfW6UiJP2iQMA0GCSqGSIb3DQEBCwUAA4IBAQBKVczMFdHl
yg79pfqtAdcex97XrcH85D9fHeM1WkJEOIMtSWFXOkCTnr3iPvtP11d3ObNT+gu0
njjH5xcVxBfcXuB8fFtVdgH38dTs/HqeLQYz1iF8luG8F9i0FOQb8P6tyD7BaRn8
7MQoMhay5VWF+zubAKac7IxcdnGpOEl7rGnKixaDul/VTgW9faTg69QBO2lzla1+
dWotBc/zK9WCHYSaX7IsHJBjYU1mSxa29myjCGGOmk2pXZP5yB/9NZSzkQkje87o
Qc7UCbvUWX6qBFZnFpehBucXfQlsQizCOA9GykjfpuFAw8g9W6MzBclbVhEi8VaA
G1xBoiCDrqfh
-----END CERTIFICATE-----

Create Widgets Utils

There are some Widgets utils that I would like to propose. I'll make a PR for it

IP Subject Alternative Name (SAN) is not parsed properly.

I have an X509 cert with IP addresses in the SAN. Ideally, SAN can support the following types of data

  • DNS
  • IP
  • URI
  • Email
  • RID
  • DirName
  • OtherName

Except for IP address, everything can be converted to string type (i might be wrong here). But for IP address, the X509Utils.x509CertificateFromPem(res.certificate.pem).subjectAlternativNames returns a malformed string. I had to explicitly convert this to a proper IP format by parsing the integer type.

  var sanIPs = X509Utils.x509CertificateFromPem(res.certificate.pem)
      .subjectAlternativNames
      .map((n) => Uint8List.fromList(n.codeUnits).join("."))
      .toList();
  print('Cert SAN: ${sanIPs}');

I would be great if this library can support the IP SAN also.

Upgrade dependency to json_annotation

Because basic_utils 2.6.3 depends on json_annotation >=2.0.0 <=3.0.1 and no versions of basic_utils match >2.6.3 <3.0.0, basic_utils ^2.6.3 requires json_annotation >=2.0.0 <=3.0.1.

Current version of json_annotation is 3.1.0

Add null safety support

Since a few packages depend on this package, it would be great if this could be adopted to null safety.

Organizational Unit number is wrong

ECSignature - base64 string

Hi, I can't find any example, is it possible to explain how to convert ECSignature to base64 signature?

ECSignature ecSign(ECPrivateKey privateKey, Uint8List dataToSign, {String algorithmName = 'SHA-1/ECDSA'});

HttpUtils.addQueryParameterToUrl not working

I have the follow code:

static Future get(String action, [Map args]) async {
    var url = HttpUtils.addQueryParameterToUrl('$baseUrl/$action', args);
    // var url = '$baseUrl/$action';

But for some reason, nothing happens. But if I use only the second line var url = '$baseUrl/$action' it works.

Could I be missing something?

http: ^0.12.0+2
basic_utils: ^1.6.0
flutter --version
Flutter 1.7.8+hotfix.4 โ€ข channel stable โ€ข
https://github.com/flutter/flutter.git
Framework โ€ข revision 20e59316b8 (4 weeks ago) โ€ข 2019-07-18 20:04:33 -0700
Engine โ€ข revision fee001c93f
Tools โ€ข Dart 2.4.0

Missing import for EC private keys in PKCS#8 encoding

Thanks for your very helpful library that I could use many times in my Cross platform cryptography project that is supporting a lot of frameworks (Java, PHP, C#, JavaScript, NodeJs, Golang, Python and Dart).

When trying to run a compatible Dart version of an ECDSA signature using the curve PRIME256V1 and SHA-256 hashing I encountered the problem that your import function ("CryptoUtils.ecPrivateKeyFromPem") is only accepting an EC private key in traditional = SEC1 encoding but not in a PKCS#8 encoding that is widely used in Java etc.

Below you find a full running program that is showing the issue - the SEC1 encoded private key signs and verifies the signature against a plaintext, the PKCS#8 encoded key is failing (that's why I'm surrounding the function call with a "try/catch" construct) and in the end I'm presenting a rough coded import of an EC private key in PKCS#8 encoding that signs and verifies successfully.

Just a note regarding the EC keys - they are sample keys I used and published in my project, so don't worry.

BTW: a good place for choosing the SEC1- or PKCS#8-import could be in the PEM-header line - a SEC1 header is "BEGIN EC PRIVATE KEY", the PKCS#8 header line is "BEGIN PRIVATE KEY".

Full source code:

import 'dart:typed_data';
import 'package:pointycastle/asn1.dart';
import 'package:pointycastle/asn1/object_identifiers.dart';
import "package:pointycastle/export.dart";
import 'package:pointycastle/src/utils.dart';
import 'package:basic_utils/basic_utils.dart';

void main() {
/* add in pubspec.yaml:
dependencies:
  pointycastle: ^3.1.1
  basic_utils: ^3.4.0
 */
  // https://pub.dev/packages/pointycastle
  // https://github.com/bcgit/pc-dart/
  // https://pub.dev/packages/basic_utils
  // https://github.com/Ephenodrom/Dart-Basic-Utils

  print('Import EC keys using Basic Utils and Pointycastle');

/* EC key generation using OpenSSL:
ecdsa private key generation in traditional = sec1 encoding:
openssl ecparam -name prime256v1 -genkey -noout -out ecdsa_secp256r1_cpc_privatekey_sec1.pem
ecdsa public key generation:
openssl ec -in ecdsa_secp256r1_cpc_privatekey_sec1.pem -pubout -out ecdsa_secp256r1_cpc_publickey_sec1.pem
convert the ec private key to pkcs#8 encoding
openssl pkcs8 -topk8 -nocrypt -in ecdsa_secp256r1_cpc_privatekey_sec1.pem -out ecdsa_secp256r1_cpc_privatekey_pkcs8.pem
*/

  // import the EC private key in OpenSSL traditional format = SEC1 encoding
  ECPrivateKey ecPrivateKeyImport =
      CryptoUtils.ecPrivateKeyFromPem(loadEcPrivateKeyPemSec1());
  // import the EC public key
  ECPublicKey ecPublicKeyImport =
      CryptoUtils.ecPublicKeyFromPem(loadEcPublicKeyPem());

  // test that EC signature is working
  final dataToSignString = 'The quick brown fox jumps over the lazy dog';
  final dataToSign = createUint8ListFromString(dataToSignString);
  print(
      '\n* * * sign the plaintext with the EC private key in SEC1 encoding * * *');
  ECSignature ecSignature = ecSign(ecPrivateKeyImport, dataToSign);
  print(
      '* * * verify the signature against the plaintext with the EC public key * * *');
  bool verified = ecVerify(ecPublicKeyImport, dataToSign, ecSignature);
  print('signature verified: ' + verified.toString()); // true = working

  // import the EC private key in PKCS#8 encoding will fail
  try {
    print('\ntrying to import the PKCS#8 encoded EC private key');
    ECPrivateKey ecPrivateKeyImport =
        CryptoUtils.ecPrivateKeyFromPem(loadEcPrivateKeyPemPkcs8());
  } on Exception catch (e) {
    // Anything else that is an exception
    print('Unknown exception: $e');
  } catch (e) {
    // No specified type, handles all
    print('Something really unknown: $e');
  }
/* ECPrivateKey ecPrivateKeyImport = CryptoUtils.ecPrivateKeyFromPem(loadEcPrivateKeyPemPkcs8());
Unhandled exception:
type 'ASN1Sequence' is not a subtype of type 'ASN1OctetString' in type cast
#0      CryptoUtils.ecPrivateKeyFromDerBytes (package:basic_utils/src/CryptoUtils.dart:635:44)
#1      CryptoUtils.ecPrivateKeyFromPem (package:basic_utils/src/CryptoUtils.dart:625:12)
#2      main (package:dartprojectspointycastle/CrossPlatformCryptography/EcKeyExportImportBasicUtils.dart:69:50)
#3      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:283:19)
#4      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
*/

  // try my own import function
  print(
      '\ntrying to import the PKCS#8 encoded EC private key using PKCS8 decode function');
  // get the data from PEM
  Uint8List ecPrivateKeyPkcs8Der =
      CryptoUtils.getBytesFromPEMString(loadEcPrivateKeyPemPkcs8());
  //ECPrivateKey ecPrivateKeyImportPkcs8 = ecPrivateKeyFromDerBytesOwn(ecPrivateKeyPkcs8Der);
  ECPrivateKey ecPrivateKeyImportPkcs8 =
      ecPrivateKeyFromDerBytesPkcs8(ecPrivateKeyPkcs8Der);
  print(
      '* * * sign the plaintext with the EC private key in PKCS#8 encoding * * *');
  ECSignature ecSignaturePkcs8 = ecSign(ecPrivateKeyImportPkcs8, dataToSign);
  print(
      '* * * verify the signature against the plaintext with the EC public key * * *');
  bool verifiedPkcs8 =
      ecVerify(ecPublicKeyImport, dataToSign, ecSignaturePkcs8);
  print('signature verified: ' + verifiedPkcs8.toString());
}

// the new - rough coded - function
///
/// Decode the given [bytes] in PKCS8 encoding into an [ECPrivateKey].
///
ECPrivateKey ecPrivateKeyFromDerBytesPkcs8(Uint8List bytes) {
  ASN1Parser asn1Parser = ASN1Parser(bytes);
  ASN1Sequence topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
  ASN1Sequence innerSeq = topLevelSeq.elements!.elementAt(1) as ASN1Sequence;
  ASN1ObjectIdentifier b2 =
      innerSeq.elements!.elementAt(1) as ASN1ObjectIdentifier;
  String? b2Data = b2.objectIdentifierAsString;
  Map<String, dynamic>? b2Curvedata =
      ObjectIdentifiers.getIdentifierByIdentifier(b2Data);
  dynamic curveName;
  if (b2Curvedata != null) {
    curveName = b2Curvedata['readableName'];
  }
  // get the octet string data for the private key der data
  ASN1OctetString octetString =
      topLevelSeq.elements!.elementAt(2) as ASN1OctetString;
  asn1Parser = ASN1Parser(octetString.valueBytes);
  ASN1Sequence octetStringSeq = asn1Parser.nextObject() as ASN1Sequence;
  ASN1OctetString octetStringKeyData =
      octetStringSeq.elements!.elementAt(1) as ASN1OctetString;
  // now generate the key
  Uint8List privateKeyDer = octetStringKeyData.valueBytes!;
  return ECPrivateKey(
      decodeBigInt(privateKeyDer), ECDomainParameters(curveName));
}

// the original import function
///
/// Decode the given [bytes] into an [ECPrivateKey].
///
ECPrivateKey ecPrivateKeyFromDerBytesOrg(Uint8List bytes) {
  var asn1Parser = ASN1Parser(bytes);
  var topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
  var privateKeyAsOctetString =
      topLevelSeq.elements!.elementAt(1) as ASN1OctetString;
  var choice = topLevelSeq.elements!.elementAt(2);
  var s = ASN1Sequence();
  var parser = ASN1Parser(choice.valueBytes);
  while (parser.hasNext()) {
    s.add(parser.nextObject());
  }
  var curveNameOi = s.elements!.elementAt(0) as ASN1ObjectIdentifier;
  var curveName;
  var data = ObjectIdentifiers.getIdentifierByIdentifier(
      curveNameOi.objectIdentifierAsString);
  if (data != null) {
    curveName = data['readableName'];
  }
  var x = privateKeyAsOctetString.valueBytes!;
  return ECPrivateKey(decodeBigInt(x), ECDomainParameters(curveName));
}

ECSignature ecSign(ECPrivateKey privateKey, Uint8List dataToSign) {
  return CryptoUtils.ecSign(privateKey, dataToSign,
      algorithmName: 'SHA-256/ECDSA');
}

bool ecVerify(
    ECPublicKey publicKey, Uint8List dataToSign, ECSignature signature) {
  return CryptoUtils.ecVerify(publicKey, dataToSign, signature,
      algorithm: 'SHA-256/ECDSA');
}

Uint8List createUint8ListFromString(String s) {
  var ret = new Uint8List(s.length);
  for (var i = 0; i < s.length; i++) {
    ret[i] = s.codeUnitAt(i);
  }
  return ret;
}

// don't worry - it's a sample key
String loadEcPublicKeyPem() {
  return ('''-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMZHnt1D1tddLNGlEHXEtEw5K/G5Q
HkgaLi+IV84oiV+THv/DqGxYDX2F5JOkfyv36iYSf5lfIC7q9el4YLnlwA==
-----END PUBLIC KEY-----''');
}

// don't worry - it's a sample key
String loadEcPrivateKeyPemSec1() {
  return ('''-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIHIj7f4Lpc8O/13tdmDrv7y1ICFGfu4BqOVZJlNAfoFFoAoGCCqGSM49
AwEHoUQDQgAEMZHnt1D1tddLNGlEHXEtEw5K/G5QHkgaLi+IV84oiV+THv/DqGxY
DX2F5JOkfyv36iYSf5lfIC7q9el4YLnlwA==
-----END EC PRIVATE KEY-----''');
}

// don't worry - it's a sample key
String loadEcPrivateKeyPemPkcs8() {
  return ('''-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgciPt/gulzw7/Xe12
YOu/vLUgIUZ+7gGo5VkmU0B+gUWhRANCAAQxkee3UPW110s0aUQdcS0TDkr8blAe
SBouL4hXziiJX5Me/8OobFgNfYXkk6R/K/fqJhJ/mV8gLur16XhgueXA
-----END PRIVATE KEY-----''');
}

Support EC CSR

Currently only RSA CSR generation is supported. RSA is deprecated for CSR. How can we add support for EC csr??

Using Method

i'm using method like this,

Future<Map<String, dynamic>> deleteForJson(String url, {Map<String, String> queryParameters, Map<String, String> headers}) async { Map<String, dynamic> response = await HttpUtils.deleteForJson(url, queryParameters: queryParameters, headers: headers); Map responseJson = json.decode(response); print(responseJson); return responseJson; }
But I'm getting error
The argument type 'Map<String, dynamic>' can't be assigned to the parameter type 'String'.
Something mistake ?

Support for PKCS#1 format keys

Is there any support for PKCS#1 format keys in the future? I see the current implementation only supports PKCS#8 format keys, it would be a great addition to the existing functionalities in the package.

RangeError was thrown: Value not in range

When I was decoding this certificate, I ran into the error below:

[ +806 ms] I/flutter (28085): โ•โ•โ•ก EXCEPTION CAUGHT BY WIDGETS LIBRARY โ•žโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
[        ] I/flutter (28085): The following RangeError was thrown building:
[        ] I/flutter (28085): Value not in range: 6090798525784719588
[        ] I/flutter (28085): 
[        ] I/flutter (28085): When the exception was thrown, this was the stack:
[        ] I/flutter (28085): #0      _rangeCheck (dart:typed_data-patch/typed_data_patch.dart:4791:5)
[        ] I/flutter (28085): #1      _ByteBuffer.asUint8List (dart:typed_data-patch/typed_data_patch.dart:1931:5)
[        ] I/flutter (28085): #2      new Uint8List.view (dart:typed_data:962:19)
[        ] I/flutter (28085): #3      ASN1Parser.nextObject (package:asn1lib/asn1parser.dart:45:30)
[        ] I/flutter (28085): #4      X509Utils.x509CertificateFromPem (package:basic_utils/src/X509Utils.dart:328:33)

The PEM string is below:

-----BEGIN CERTIFICATE-----
MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC
VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T
U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp
Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx
NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv
dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv
bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49
AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA
VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku
WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP
MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX
5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ
ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg
h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==
-----END CERTIFICATE-----

The data in text format is:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 3182246526754555285 (0x2c299c5b16ed0595)
    Signature Algorithm: ecdsa-with-SHA256
        Issuer: C=US, ST=Texas, L=Houston, O=SSL Corporation, CN=SSL.com EV Root Certification Authority ECC
        Validity
            Not Before: Feb 12 18:15:23 2016 GMT
            Not After : Feb 12 18:15:23 2041 GMT
        Subject: C=US, ST=Texas, L=Houston, O=SSL Corporation, CN=SSL.com EV Root Certification Authority ECC
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (384 bit)
                pub:
                    04:aa:12:47:90:98:1b:fb:ef:c3:40:07:83:20:4e:
                    f1:30:82:a2:06:d1:f2:92:86:61:f2:f6:21:68:ca:
                    00:c4:c7:ea:43:00:54:86:dc:fd:1f:df:00:b8:41:
                    62:5c:dc:70:16:32:de:1f:99:d4:cc:c5:07:c8:08:
                    1f:61:16:07:51:3d:7d:5c:07:53:e3:35:38:8c:df:
                    cd:9f:d9:2e:0d:4a:b6:19:2e:5a:70:5a:06:ed:be:
                    f0:a1:b0:ca:d0:09:29
                ASN1 OID: secp384r1
                NIST CURVE: P-384
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                5B:CA:5E:E5:DE:D2:81:AA:CD:A8:2D:64:51:B6:D9:72:9B:97:E6:4F
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 Authority Key Identifier: 
                keyid:5B:CA:5E:E5:DE:D2:81:AA:CD:A8:2D:64:51:B6:D9:72:9B:97:E6:4F

            X509v3 Key Usage: critical
                Digital Signature, Certificate Sign, CRL Sign
    Signature Algorithm: ecdsa-with-SHA256
         30:65:02:31:00:8a:e6:40:89:37:eb:e9:d5:13:d9:ca:d4:6b:
         24:f3:b0:3d:87:46:58:1a:ec:b1:df:6f:fb:56:ba:70:6b:c7:
         38:cc:e8:b1:8c:4f:0f:f7:f1:67:76:0e:83:d0:1e:51:8f:02:
         30:3d:f6:23:28:26:4c:c6:60:87:93:26:9b:b2:35:1e:ba:d6:
         f7:3c:d1:1c:ce:fa:25:3c:a6:1a:81:15:5b:f3:12:0f:6c:ee:
         65:8a:c9:87:a8:f9:07:e0:62:9a:8c:5c:4a
SHA1 Fingerprint=4C:DD:51:A3:D1:F5:20:32:14:B0:C6:C5:32:23:03:91:C7:46:42:6D

ASN.1 JavaScript decoder of this certificate is at http://lapo.it/asn1js/#MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgxNTIzWjB_MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuBBAAiA2IABKoSR5CYG_vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMAVIbc_R_fALhBYlzccBYy3h-Z1MzFB8gIH2EWB1E9fVwHU-M1OIzfzZ_ZLg1KthkuWnBaBu2-8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl-ZPMA8GA1UdEwEB_wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX5k8wDgYDVR0PAQH_BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN-vp1RPZytRrJPOwPYdGWBrssd9v-1a6cGvHOMzosYxPD_fxZ3YOg9AeUY8CMD32IygmTMZgh5Mmm7I1HrrW9zzRHM76JTymGoEVW_MSD2zuZYrJh6j5B-BimoxcSg

Not sure how to proceed to debug, if you can point a direction or have a suggestion, I would appreciate!

Suggestion adding the Pascal case

A simple addition to support Pascal casing:

  /// PascalCase CamelCase string
  /// Example: your name => YourName
  String? get pascalCase {
    if (isEmpty) {
      return null;
    }

    final separatedWords = split(RegExp(r'[!@#<>?":`~;[\]\\|=+)(*&^%-\s_]+'));
    var newString = '';

    for (final word in separatedWords) {
      newString += word[0].toUpperCase() + word.substring(1).toLowerCase();
    }

    return newString;
  }
}

'ASN1Sequence' is not a subtype of type 'ASN1Integer' in type cast

Hello, and thank you for this library.

I have an issue with extracting RSA Public ket from the RSA Certificate.
The given Certificate:

-----BEGIN CERTIFICATE-----
MIIDWzCCAkOgAwIBAgIQTX9LRo00ZpDIAvINyDRqpzANBgkqhkiG9w0BAQsFADA7
MRIwEAYDVQQKEwlNZWR0cm9uaWMxJTAjBgNVBAMMHFBpbGxjYW3ihKIgR2VuaXVz
IElzc3VpbmcgQ0EwHhcNMjExMjEyMTYxMDU3WhcNMjMxMjEyMTYxMDU2WjAeMRww
GgYDVQQDExNwYXRjaCBjZXJ0aWZpY2F0ZSAxMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAm/97dBCFekttJrq5VwVlT/D3Qvs7wBhl776O+q5galKtg2gV
2mJVLSlC4w6jIVm31KpHug1TWoHHiwhTpp8deLSDI6uMj6zOZXTRhU0XavAugREZ
jFkxtp2IzmLhxaxAWE+xrX2YeuCsRVPVF3J/sLmAt6PUmuHYE+xnENfEfxM+Kksu
MA8vE1uHD/jmr36IiznAQ7z6aDiJrAG9VC0hppfRpGqO+jSYk3ReQMSI2PG8W+VC
mO+Um8HeGZ7F+NPWxbnnHm7y8TDdsTmfvsp38cbskGgK0/OT+GDkDO4tdIY15uRm
jM1azhNEvfFaaZvDh/RQ/9mWbEoPrhy9dGtt8wIDAQABo3gwdjAfBgNVHSMEGDAW
gBT4wEB5tLJ7Q/nmGlHMh9VIh9Dd0TAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/
BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDAjAdBgNVHQ4EFgQUJiFDXdiOpL9J
v6DIZLKfbOlnR3wwDQYJKoZIhvcNAQELBQADggEBAG/m8Zz5QD/Or1HY1v+j0hK9
j4x5EGeVUm3eRwCWxuBY/4+4SzloY09CuV6eVM4d8b7oCjvGvOw9r5YRtYVomsiR
+HljSaVevikCjSYGHk/FqAEBjKKukZ99uqVgBnKyHgoYHOurUM1D2+4313vWnHWg
WZttzq2wDd1YGE2xT3gxc5GL9KJBuEklTlF/Ve3Wq/1yrGuSaXM/Ig1eqBAc/fgV
ZpB8LNCbmJ9ierNLab78DVzNeoRd0vTZ9sUSghdpOmXL0RlMgniqdaeKwYDiRZb/
U0+vI6AZYMx15Es0eGGEYSPgjGBspB4Clbuw08RLYlbB4raA0TBAq8wR3pAK9dY=
-----END CERTIFICATE-----

And when i try to call:
CryptoUtils.rsaPublicKeyFromPem(cert)

I receive an error:
'ASN1Sequence' is not a subtype of type 'ASN1Integer' in type cast
What can be the reason?

pointycastle upgrade and asn1lib migration

It caught my eye that pubspec.yaml still referenced old dependencies:

-  pointycastle: ^1.0.2
-  asn1lib: ^0.6.5

Even more fascinating is that pointycastle: ^2.0.0 includes an asn1 implementation, so the asn1lib dependency could be dropped/replaced -- but I know you know this @Ephenodrom.

For fun, I tried to upgrade this package, but I ran into 3 roadblocks that I cannot seem to overcome. It appears that pointycastle's asn1 implementation is not quite ready for prime time.

However, I thought it would be worth sharing my discoveries to date to aid the eventual migration:

  1. Calls to ASN1ObjectIdentifier.registerFrequentNames(); may be removed; there does not seem to be an equivalent. (And honestly, this strikes me as an odd API design for asn1lib, but I am not an expert on ASN1.) ๐Ÿ‘
  2. Most old calls to .encodedBytes need to be replaced with calls to .encode(). (It looks like the old ASN1lib would trigger an encoding if encodedBytes was called before encode(), but the new implementation simply returns null. A getter should not maybe do something expensive, so I'm OK with encodedBytes being a simple getter, but I would expect it to assert if it is illegal to call before encode().)
  3. ASN1BitString constructor needs to add parameter name like stringValues. (Honestly, I would rethink this to be more backwards compatible with the old asn1lib. You can have alternate constructors or factory methods to handle different scenarios.)
  4. ASN1OctetString constructor needs to add parameter name like octets. (Same issue as ASN1BitString.)
  5. Calls to .contentBytes(). need to be replaced with .valueBytes.
  6. Calls to .valueAsBigInteger need to replaced with .integer.
  7. Calls to .identifier need to be replaced with .objectIdentifierAsString.
  8. For ASN1UtcTime, calls to .dateTimeValue need to be replaced with .time.
  9. Calls to .valueBytes() need to be replaced with .valueBytes.
  10. Curve Name translations can now be radically simplified from:
var curveNameOi = s.elements.elementAt(0) as ASN1ObjectIdentifier;
var curveName;
ASN1ObjectIdentifier.DN.keys.forEach((element) {
  if (ASN1ObjectIdentifier.DN[element] == curveNameOi.identifier) {
    curveName = element;
  }
});

to:

var curveNameOi = s.elements.elementAt(0) as ASN1ObjectIdentifier;
final curveName = curveNameOi.readableName;

๐ŸŽ‰

After all these changes, I could not get past 9 unit test failures. Of these 9 failures, there are basically 3 outstanding issues, all of which seem to be related to pointycastle's ASN1 implementation:

  1. This unit test failure:
00:13 +54 -1: test/x509_utils_test.dart: Test generateRsaCsrPem [E]                                                                        
  NoSuchMethodError: The getter 'iterator' was called on null.
  Receiver: null
  Tried calling: iterator
  dart:core                                                        List.addAll
  package:pointycastle/asn1/primitives/asn1_bit_string.dart 82:11  ASN1BitString.encode
  package:pointycastle/asn1/primitives/asn1_sequence.dart 69:16    ASN1Sequence._childLength.<fn>
  dart:core                                                        List.forEach
  package:pointycastle/asn1/primitives/asn1_sequence.dart 68:14    ASN1Sequence._childLength
  package:pointycastle/asn1/primitives/asn1_sequence.dart 51:25    ASN1Sequence.encode
  package:pointycastle/asn1/primitives/asn1_sequence.dart 69:16    ASN1Sequence._childLength.<fn>
  dart:core                                                        List.forEach
  package:pointycastle/asn1/primitives/asn1_sequence.dart 68:14    ASN1Sequence._childLength
  package:pointycastle/asn1/primitives/asn1_sequence.dart 51:25    ASN1Sequence.encode
  package:basic_utils/src/X509Utils.dart 125:54                    X509Utils.generateRsaCsrPem
  test/x509_utils_test.dart 279:25                                 main.<fn>

The ultimate code is simply:

    var blockDN = ASN1Sequence();
    blockDN.add(ASN1Integer(BigInt.from(0)));
    blockDN.add(encodedDN);
    blockDN.add(_makePublicKeyBlock(publicKey));
    blockDN.add(ASN1Null(tag: 0xA0)); // let's call this WTF
...
    blockDN.encode()

The blockDN setup is no different -- the old code called blockDN.encodedBytes instead.

  1. Incorrect Public Key Length -- pubKeyLength is 2168 instead of 2048, for example. The value seems to be consistently +120 (a 4096 became 4216), but I cannot figure out what is wrong. This appears to be an issue with pointycastle's ASN1 implementation.

  2. I can't seem to get this to work:

  static RSAPublicKey rsaPublicKeyFromDERBytes(Uint8List bytes) {
    var asn1Parser = ASN1Parser(bytes);
    var topLevelSeq = asn1Parser.nextObject() as ASN1Sequence;
    var publicKeyBitString = topLevelSeq.elements[1];

    var publicKeyAsn = ASN1Parser(publicKeyBitString.valueBytes);
    ASN1Sequence publicKeySeq = publicKeyAsn.nextObject();
    var modulus = publicKeySeq.elements[0] as ASN1Integer;
    var exponent = publicKeySeq.elements[1] as ASN1Integer;

    var rsaPublicKey = RSAPublicKey(modulus.integer, exponent.integer);

    return rsaPublicKey;
  }

It says:

  UnsupportedASN1TagException: Tag 0 is not supported yet
  package:pointycastle/asn1/asn1_parser.dart 149:9  ASN1Parser._createPrimitive
  package:pointycastle/asn1/asn1_parser.dart 78:13  ASN1Parser.nextObject
  package:basic_utils/src/CryptoUtils.dart 446:46   CryptoUtils.rsaPublicKeyFromDERBytes
  test/crypto_utils_test.dart 170:30                main.<fn>

I hope this helps the eventual upgrade/migration.

`ASN1Sequence` is not a subtype of type `ASN1Integer` in type cast

When I was decoding this certificate, I ran into the error below:

#0      X509Utils.x509CertificateFromPem (package:basic_utils/src/X509Utils.dart:268:60)

The PEM string is below:

-----BEGIN CERTIFICATE-----
MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
-----END CERTIFICATE-----

The data in text format is:

Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            9b:7e:06:49:a3:3e:62:b9:d5:ee:90:48:71:29:ef:57
    Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 1999 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G3
        Validity
            Not Before: Oct  1 00:00:00 1999 GMT
            Not After : Jul 16 23:59:59 2036 GMT
        Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 1999 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G3
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:cb:ba:9c:52:fc:78:1f:1a:1e:6f:1b:37:73:bd:
                    f8:c9:6b:94:12:30:4f:f0:36:47:f5:d0:91:0a:f5:
                    17:c8:a5:61:c1:16:40:4d:fb:8a:61:90:e5:76:20:
                    c1:11:06:7d:ab:2c:6e:a6:f5:11:41:8e:fa:2d:ad:
                    2a:61:59:a4:67:26:4c:d0:e8:bc:52:5b:70:20:04:
                    58:d1:7a:c9:a4:69:bc:83:17:64:ad:05:8b:bc:d0:
                    58:ce:8d:8c:f5:eb:f0:42:49:0b:9d:97:27:67:32:
                    6e:e1:ae:93:15:1c:70:bc:20:4d:2f:18:de:92:88:
                    e8:6c:85:57:11:1a:e9:7e:e3:26:11:54:a2:45:96:
                    55:83:ca:30:89:e8:dc:d8:a3:ed:2a:80:3f:7f:79:
                    65:57:3e:15:20:66:08:2f:95:93:bf:aa:47:2f:a8:
                    46:97:f0:12:e2:fe:c2:0a:2b:51:e6:76:e6:b7:46:
                    b7:e2:0d:a6:cc:a8:c3:4c:59:55:89:e6:e8:53:5c:
                    1c:ea:9d:f0:62:16:0b:a7:c9:5f:0c:f0:de:c2:76:
                    ce:af:f7:6a:f2:fa:41:a6:a2:33:14:c9:e5:7a:63:
                    d3:9e:62:37:d5:85:65:9e:0e:e6:53:24:74:1b:5e:
                    1d:12:53:5b:c7:2c:e7:83:49:3b:15:ae:8a:68:b9:
                    57:97
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha1WithRSAEncryption
         11:14:96:c1:ab:92:08:f7:3f:2f:c9:b2:fe:e4:5a:9f:64:de:
         db:21:4f:86:99:34:76:36:57:dd:d0:15:2f:c5:ad:7f:15:1f:
         37:62:73:3e:d4:e7:5f:ce:17:03:db:35:fa:2b:db:ae:60:09:
         5f:1e:5f:8f:6e:bb:0b:3d:ea:5a:13:1e:0c:60:6f:b5:c0:b5:
         23:22:2e:07:0b:cb:a9:74:cb:47:bb:1d:c1:d7:a5:6b:cc:2f:
         d2:42:fd:49:dd:a7:89:cf:53:ba:da:00:5a:28:bf:82:df:f8:
         ba:13:1d:50:86:82:fd:8e:30:8f:29:46:b0:1e:3d:35:da:38:
         62:16:18:4a:ad:e6:b6:51:6c:de:af:62:eb:01:d0:1e:24:fe:
         7a:8f:12:1a:12:68:b8:fb:66:99:14:14:45:5c:ae:e7:ae:69:
         17:81:2b:5a:37:c9:5e:2a:f4:c6:e2:a1:5c:54:9b:a6:54:00:
         cf:f0:f1:c1:c7:98:30:1a:3b:36:16:db:a3:6e:ea:fd:ad:b2:
         c2:da:ef:02:47:13:8a:c0:f1:b3:31:ad:4f:1c:e1:4f:9c:af:
         0f:0c:9d:f7:78:0d:d8:f4:35:56:80:da:b7:6d:17:8f:9d:1e:
         81:64:e1:fe:c5:45:ba:ad:6b:b9:0a:7a:4e:4f:4b:84:ee:4b:
         f1:7d:dd:11
SHA1 Fingerprint=13:2D:0D:45:53:4B:69:97:CD:B2:D5:C3:39:E2:55:76:60:9B:5C:C6

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.