parsePemKey.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. const forge = require('node-forge');
  2. const APNKey = require('./APNKey');
  3. function findAndDecryptKey(pemMessages, passphrase) {
  4. let apnKey = null;
  5. pemMessages.forEach(function (message) {
  6. if (!message.type.match(/KEY/)) {
  7. return;
  8. }
  9. const key = forge.pki.decryptRsaPrivateKey(forge.pem.encode(message), passphrase);
  10. if (!key) {
  11. if (
  12. (message.procType && message.procType.type === 'ENCRYPTED') ||
  13. message.type.match(/ENCRYPTED/)
  14. ) {
  15. throw new Error('unable to parse key, incorrect passphrase');
  16. }
  17. } else if (apnKey) {
  18. throw new Error('multiple keys found in PEM file');
  19. } else {
  20. apnKey = new APNKey(key);
  21. }
  22. });
  23. return apnKey;
  24. }
  25. function apnKeyFromPem(keyPem, passphrase) {
  26. if (!keyPem) {
  27. return null;
  28. }
  29. try {
  30. const pemMessages = forge.pem.decode(keyPem);
  31. const apnKey = findAndDecryptKey(pemMessages, passphrase);
  32. if (apnKey) {
  33. return apnKey;
  34. }
  35. } catch (e) {
  36. if (e.message.match(/Unsupported OID/)) {
  37. throw new Error('unable to parse key, unsupported format: ' + e.oid);
  38. } else if (e.message.match(/Invalid PEM formatted message/)) {
  39. throw new Error('unable to parse key, not a valid PEM file');
  40. } else if (e.message.match(/multiple keys/)) {
  41. throw e;
  42. } else if (e.message.match(/unable to parse key/)) {
  43. throw e;
  44. }
  45. }
  46. throw new Error('unable to parse key, no private key found');
  47. }
  48. module.exports = apnKeyFromPem;