bcgit / pc-dart

Pointy Castle - Dart Derived Bouncy Castle APIs
MIT License
241 stars 125 forks source link

Official ASN1 example not wroking, can't encode bit string. #165

Open SzczurekYT opened 2 years ago

SzczurekYT commented 2 years ago

In ASN1 Encoding Tutorial there is an example. When run the return of topLevelSeq.encodedBytes is null. From what I understand and tested you need to execute topLevelSeq.encode(); first but then an error is thrown. image The stack trace points to line 84 in ASN1BitString. It seems that stringValues field is null while it shouldn't.

SzczurekYT commented 2 years ago

I was able to rewrite this code to make it work. I'm gonna send it tomorrow, as it's a bit late today in my timezone.

SzczurekYT commented 2 years ago

Sorry for veery late response, here is my working version, I changed the BitString part and also used some code for chunking as there were no StringUtils class. In this example you just need to provide the public key and it will work.

  const beginPublicKey = '-----BEGIN PUBLIC KEY-----';
  const endPublicKey = '-----END PUBLIC KEY-----';

  // Create a new RSA pulic key
  RSAPublicKey publicKey;

  // Create the top level sequence
  var topLevelSeq = ASN1Sequence();

  // Create the sequence holding the algorithm information
  var algorithmSeq = ASN1Sequence();
  var paramsAsn1Obj = ASN1Object.fromBytes(Uint8List.fromList([0x5, 0x0]));
  algorithmSeq
      .add(ASN1ObjectIdentifier.fromIdentifierString('1.2.840.113549.1.1.1'));
  algorithmSeq.add(paramsAsn1Obj);

  // Create the constructed ASN1BitString
  var keySequence = ASN1Sequence();
  keySequence.add(ASN1Integer(publicKey.modulus));
  keySequence.add(ASN1Integer(publicKey.exponent));
  keySequence.encode(encodingRule: ASN1EncodingRule.ENCODING_DER);
  var publicKeySeqBitString =
      ASN1BitString(stringValues: keySequence.encodedBytes!);

  // Add ASN1 objects to the top level sequence
  topLevelSeq.add(algorithmSeq);
  topLevelSeq.add(publicKeySeqBitString);
  topLevelSeq.encode(encodingRule: ASN1EncodingRule.ENCODING_DER);

  // Util function for splitting string into equal parts.
  // Taken from basic_utils package.
  List<String> chunk(String s, int chunkSize) {
    var chunked = <String>[];
    for (var i = 0; i < s.length; i += chunkSize) {
      var end = (i + chunkSize < s.length) ? i + chunkSize : s.length;
      chunked.add(s.substring(i, end));
    }
    return chunked;
  }

  // Encode base64
  var dataBase64 = base64.encode(topLevelSeq.encodedBytes!);
  var chunks = chunk(dataBase64, 64);

  print('$beginPublicKey\n${chunks.join('\n')}\n$endPublicKey');
ww-daniel-mora commented 1 year ago

@SzczurekYT it looks like basic_utils has a matching chunk method that the example may be referring to

SzczurekYT commented 1 year ago

Yeah, the method here is taken from it, as the comment says.