parsePkcs12.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. const forge = require('node-forge');
  2. const APNKey = require('./APNKey');
  3. const APNCertificate = require('./APNCertificate');
  4. function decryptPkcs12FromAsn1(asn1, passphrase) {
  5. try {
  6. return forge.pkcs12.pkcs12FromAsn1(asn1, false, passphrase);
  7. } catch (e) {
  8. // OpenSSL-exported files need an empty string, if no password was specified
  9. // during export.
  10. if (passphrase) {
  11. throw e;
  12. }
  13. return forge.pkcs12.pkcs12FromAsn1(asn1, false, '');
  14. }
  15. }
  16. function apnCredentialsFromPkcs12(p12Data, passphrase) {
  17. if (!p12Data) {
  18. return undefined;
  19. }
  20. let pkcs12;
  21. try {
  22. const asn1 = forge.asn1.fromDer(p12Data.toString('binary'), false);
  23. pkcs12 = decryptPkcs12FromAsn1(asn1, passphrase);
  24. } catch (e) {
  25. if (e.message.match('Invalid password')) {
  26. throw new Error('unable to parse credentials, incorrect passphrase');
  27. } else {
  28. throw new Error('unable to parse credentials, not a PFX/P12 file');
  29. }
  30. }
  31. const credentials = { key: null, certificates: [] };
  32. pkcs12.safeContents.forEach(function (safeContents) {
  33. safeContents.safeBags.forEach(function (safeBag) {
  34. if (safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag) {
  35. if (credentials.key) {
  36. throw new Error('multiple keys found in PFX/P12 file');
  37. }
  38. credentials.key = new APNKey(safeBag.key);
  39. } else if (safeBag.type === forge.pki.oids.certBag) {
  40. credentials.certificates.push(new APNCertificate(safeBag.cert));
  41. }
  42. });
  43. });
  44. return credentials;
  45. }
  46. module.exports = apnCredentialsFromPkcs12;