Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write signature #74

Closed
1 task
ueman opened this issue Aug 4, 2024 · 3 comments · Fixed by #87
Closed
1 task

Write signature #74

ueman opened this issue Aug 4, 2024 · 3 comments · Fixed by #87
Labels
help wanted Extra attention is needed package: passkit Issues relevant for the "passkit" package

Comments

@ueman
Copy link
Owner

ueman commented Aug 4, 2024

@ueman ueman added help wanted Extra attention is needed package: passkit Issues relevant for the "passkit" package labels Aug 4, 2024
@ueman ueman changed the title Write signature when creating a pass Write signature Aug 4, 2024
@ueman
Copy link
Owner Author

ueman commented Aug 4, 2024

There's some code at which may help with it: https://github.com/tomasmcguinness/dotnet-passbook/blob/master/Passbook.Generator/PassGenerator.cs

// How to create a `RSAPrivateKey` from a pem file

import 'dart:typed_data';
import 'package:passkit/src/apple_wwdr_certificate.dart';
import 'package:pem/pem.dart';
import 'package:pkcs7/pkcs7.dart';
import 'package:pointycastle/pointycastle.dart';

RSAPrivateKey _createPrivateKey(String userCertificate) {
  final pem = decodePemBlocks(PemLabel.privateKey, userCertificate);

  final modulus =
      ASN1Object.fromBytes(Uint8List.fromList(pem[1])) as ASN1Integer;
  final exponent =
      ASN1Object.fromBytes(Uint8List.fromList(pem[3])) as ASN1Integer;
  final p = ASN1Object.fromBytes(Uint8List.fromList(pem[4])) as ASN1Integer;
  final q = ASN1Object.fromBytes(Uint8List.fromList(pem[5])) as ASN1Integer;

  return RSAPrivateKey(
    modulus.integer!,
    exponent.integer!,
    p.integer,
    q.integer,
  );
}

@ueman
Copy link
Owner Author

ueman commented Aug 29, 2024

As a temporary solution, we could provide a callback for writing the signature. There are multiple examples for signing PKPass files with OpenSSL, and there are also OpenSSL bindings for Dart/Flutter. I however intend this library (and it's dependencies) to be Dart only.

Pseudo code example:

final pass = PkPass(...);
final pkPassFile = pass.create(signatureWriter: (contentHashes) {
  // create signature here based on the contentHashes
  return signature;
});

@ueman
Copy link
Owner Author

ueman commented Sep 13, 2024

Maybe something like this could work?

import 'dart:typed_data';

import 'package:passkit/src/apple_wwdr_certificate.dart';
import 'package:pem/pem.dart';
import 'package:pkcs7/pkcs7.dart';
import 'package:pointycastle/pointycastle.dart';

Uint8List writeSignature(
  String userCertificate, // this is private key and certificate in one file
  Uint8List manifestBytes, // I'm guessing this should be the manifest content, not the hash of the manifest
) {
  final privateKey = _createPrivateKey(userCertificate);
  final issuer = X509.fromPem(userCertificate);

  final pkcs7Builder = Pkcs7Builder();

  pkcs7Builder.addCertificate(issuer);
  pkcs7Builder.addCertificate(wwdrG4);

  final signerInfo = Pkcs7SignerInfoBuilder.rsa(
    issuer: issuer,
    privateKey: privateKey,
    digestAlgorithm: HashAlgorithm.sha1,
  );

  signerInfo.addSMimeDigest(digest: manifestBytes, signingTime: DateTime.now());
  pkcs7Builder.addSignerInfo(signerInfo);

  final pkcs7 = pkcs7Builder.build();
  return pkcs7.der;
}

RSAPrivateKey _createPrivateKey(String certificate) {
  final pem = decodePemBlocks(PemLabel.privateKey, certificate);

  final modulus =
      ASN1Object.fromBytes(Uint8List.fromList(pem[1])) as ASN1Integer;
  final exponent =
      ASN1Object.fromBytes(Uint8List.fromList(pem[3])) as ASN1Integer;
  final p = ASN1Object.fromBytes(Uint8List.fromList(pem[4])) as ASN1Integer;
  final q = ASN1Object.fromBytes(Uint8List.fromList(pem[5])) as ASN1Integer;

  return RSAPrivateKey(
    modulus.integer!,
    exponent.integer!,
    p.integer,
    q.integer,
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed package: passkit Issues relevant for the "passkit" package
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant