UNPKG

@sexycoders/libauth.js

Version:

A full service for asymetric passwordless authentication.

1,249 lines (1,183 loc) 76.4 kB
var ASSERT = require('assert'); var ASN1 = require('../../lib/asn1'); var MD = require('../../lib/md.all'); var PKI = require('../../lib/pki'); var UTIL = require('../../lib/util'); (function() { var _pem = { privateKey: '-----BEGIN RSA PRIVATE KEY-----\r\n' + 'MIICXQIBAAKBgQDL0EugUiNGMWscLAVM0VoMdhDZEJOqdsUMpx9U0YZI7szokJqQ\r\n' + 'NIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMGTkP3VF29vXBo+dLq5e+8VyAy\r\n' + 'Q3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGtvnM+z0MYDdKo80efzwIDAQAB\r\n' + 'AoGAIzkGONi5G+JifmXlLJdplom486p3upf4Ce2/7mqfaG9MnkyPSairKD/JXvfh\r\n' + 'NNWkkN8DKKDKBcVVElPgORYT0qwrWc7ueLBMUCbRXb1ZyfEulimG0R3kjUh7NYau\r\n' + 'DaIkVgfykXGSQMZx8FoaT6L080zd+0emKDDYRrb+/kgJNJECQQDoUZoiC2K/DWNY\r\n' + 'h3/ppZ0ane2y4SBmJUHJVMPQ2CEgxsrJTxet668ckNCKaOP/3VFPoWC41f17DvKq\r\n' + 'noYINNntAkEA4JbZBZBVUrQFhHlrpXT4jzqtO2RlKZzEq8qmFZfEErxOT1WMyyCi\r\n' + 'lAQ5gUKardo1Kf0omC8Xq/uO9ZYdED55KwJBALs6cJ65UFaq4oLJiQPzLd7yokuE\r\n' + 'dcj8g71PLBTW6jPxIiMFNA89nz3FU9wIVp+xbMNhSoMMKqIPVPC+m0Rn260CQQDA\r\n' + 'I83fWK/mZWUjBM33a68KumRiH238v8XyQxj7+C8i6D8G2GXvkigFAehAkb7LZZd+\r\n' + 'KLuGFyPlWv3fVWHf99KpAkBQFKk3MRMl6IGJZUEFQe4l5whm8LkGU4acSqv9B3xt\r\n' + 'qROkCrsFrMPqjuuzEmyHoQZ64r2PLJg7FOuyhBnQUOt4\r\n' + '-----END RSA PRIVATE KEY-----\r\n', publicKey: '-----BEGIN PUBLIC KEY-----\r\n' + 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDL0EugUiNGMWscLAVM0VoMdhDZ\r\n' + 'EJOqdsUMpx9U0YZI7szokJqQNIwokiQ6EonNnWSMlIvy46AhnlRYn+ezeTeU7eMG\r\n' + 'TkP3VF29vXBo+dLq5e+8VyAyQ3FzM1wI4ts4hRACF8w6mqygXQ7i/SDu8/rXqRGt\r\n' + 'vnM+z0MYDdKo80efzwIDAQAB\r\n' + '-----END PUBLIC KEY-----\r\n', certificate: '-----BEGIN CERTIFICATE-----\r\n' + 'MIIDIjCCAougAwIBAgIJANE2aHSbwpaRMA0GCSqGSIb3DQEBBQUAMGoxCzAJBgNV\r\n' + 'BAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxhY2tzYnVyZzEN\r\n' + 'MAsGA1UEChMEVGVzdDENMAsGA1UECxMEVGVzdDEVMBMGA1UEAxMMbXlzZXJ2ZXIu\r\n' + 'Y29tMB4XDTEwMDYxOTE3MzYyOFoXDTExMDYxOTE3MzYyOFowajELMAkGA1UEBhMC\r\n' + 'VVMxETAPBgNVBAgTCFZpcmdpbmlhMRMwEQYDVQQHEwpCbGFja3NidXJnMQ0wCwYD\r\n' + 'VQQKEwRUZXN0MQ0wCwYDVQQLEwRUZXN0MRUwEwYDVQQDEwxteXNlcnZlci5jb20w\r\n' + 'gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMvQS6BSI0YxaxwsBUzRWgx2ENkQ\r\n' + 'k6p2xQynH1TRhkjuzOiQmpA0jCiSJDoSic2dZIyUi/LjoCGeVFif57N5N5Tt4wZO\r\n' + 'Q/dUXb29cGj50url77xXIDJDcXMzXAji2ziFEAIXzDqarKBdDuL9IO7z+tepEa2+\r\n' + 'cz7PQxgN0qjzR5/PAgMBAAGjgc8wgcwwHQYDVR0OBBYEFPV1Y+DHXW6bA/r9sv1y\r\n' + 'NJ8jAwMAMIGcBgNVHSMEgZQwgZGAFPV1Y+DHXW6bA/r9sv1yNJ8jAwMAoW6kbDBq\r\n' + 'MQswCQYDVQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExEzARBgNVBAcTCkJsYWNr\r\n' + 'c2J1cmcxDTALBgNVBAoTBFRlc3QxDTALBgNVBAsTBFRlc3QxFTATBgNVBAMTDG15\r\n' + 'c2VydmVyLmNvbYIJANE2aHSbwpaRMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF\r\n' + 'BQADgYEARdH2KOlJWTC1CS2y/PAvg4uiM31PXMC1hqSdJlnLM1MY4hRfuf9VyTeX\r\n' + 'Y6FdybcyDLSxKn9id+g9229ci9/s9PI+QmD5vXd8yZyScLc2JkYB4GC6+9D1+/+x\r\n' + 's2hzMxuK6kzZlP+0l9LGcraMQPGRydjCARZZm4Uegln9rh85XFQ=\r\n' + '-----END CERTIFICATE-----\r\n' }; var _pem_sha256 = { privateKey: '-----BEGIN RSA PRIVATE KEY-----\r\n' + 'MIIEpAIBAAKCAQEAgqu7/2ntXa9rzqiUvDD2swStK8w7MFtha/OiwzEDJng7mZUs\r\n' + 'uy7Neqh5S1Z+nWq7NP51ol//tnNCrWM6VozrJKTAEC2qj3k+bMWnjuTU7sTJHpoZ\r\n' + '9wdCqS9q7oOJhqwBxS7M9l8LNA+6I4Qj1bY1g2XeZsxEjJfCvILa3yBzztL3CxSF\r\n' + 'R36FoOo9IpzYlVcE9mqTdJgTwR43ZsFNCRAkfSqJjLKy1A2+aDxUcrom2OrLSITI\r\n' + 'CWqz5R1hFIIIB0aprjpz5F2MunciUAhTjUqrQPCtw17wmwmaeXZsu0zoq9P/VtKE\r\n' + 'AxtQkS4tqgnodBzmmgM8YemjkJAVHQzkH8jiGQIDAQABAoIBAQAMuYiPMNOKogCP\r\n' + 'mV8SjHoZqMTsVPEWnm94QbuB4o35+w9iv2IhwEcGQM2/BmdCERi16mmuLEcMj2DY\r\n' + '3abastJbOSfy61+GpTntAbp1cddCgStMrZkFs1FMhG+XVnvX/3wUpaAUBeFjanyn\r\n' + '5MBQmXPQneTwgcfTIRw3m06RF+nvI/ssIz6oHTDTTwRanTa64KYCww/fcX0XCLGw\r\n' + 'D4GYaRrBLvglp27omQCLuCBp1Dedwx5+JRnybyQm1ZYVJ0kirD/qVDRJqQN6z2N/\r\n' + '3XmvOc6yNnzNQwKDlFFs6VxLG/i/sv+TekiPIP2LIQ1V/0ojUJriRdPAe/dhER5E\r\n' + 'ku2n+k75AoGBAPDUZNyqPqFTUaLj6mdTEIvLbG0Dx0/EZTalUohFUBpJSxSUuNIS\r\n' + '6z+2dohTO5qj6Mv1JpXqXEWmRQisBl8ibizD5KJkgQW0EptmJf5BU9bnqYllgjZj\r\n' + 'jJsBixFFcwbFUwD4vg7NjYrxEv2Wjv8II0rVNbEh61F35vMNdmgMsu0TAoGBAIrm\r\n' + '7NbFDDBWREyFZKZdVhTo2AR8JyWuWdOO7EFbv+mzHy7TkgscwYlV4yeU/+TG6KLG\r\n' + 'WPo5AX2mWL/zI2Zjd2Quw002e6Y9ZIO8CUK8iocrvhNy+Bfli2XyjYZxRIILQeKX\r\n' + 'ID/h+gyzViKOXFclbUkubnm/kEGwWO8hRQvh/TWjAoGAUwbGZxUCVpfk8yVkMI8A\r\n' + 'i1FsZgEBe8yXoElKtNRAk29lRQko1rPTCrobD1CyodOUdIxl6xVLDnAOKLk10SKL\r\n' + 'nT9D2YCQwqicKZsDyi43e0WOu2GVjK6xUNctXJz21QS+Yv1eeLgA7j/Cbk6zqdTi\r\n' + 'ZfAvfIvXFtUhd/XSNnj6TqUCgYBKGrE4U6ARGbUObgwohZsrRJ4apnHsNHxP1exN\r\n' + 'Yjmc4Kc+QDmmHA1Uy7GIqIFs+IGcdd16gXc+JcUrgvfb5C0KEbi4NNz67730WhlG\r\n' + 'tXfibX/WuHuLpDceiKzgkQVPq9nWnXHjIxhYNkU54mF5TMplRJRD9+NqaD7KNSG1\r\n' + 'GTgRqQKBgQCSJ2W29p2uOrl+OcogFMSfZYkwJsKR25S/c7BAvsH7dVdtqSdBsRg2\r\n' + 'zWEwWAGyd7BJsZd0gVCea9CHfZYwDoCC4nA7sRFVLAqWfRsmrALORIiXHBYD6SrL\r\n' + 'H1G4nr6HK6/Ur0WTQQmwyz1Yw+ZhyShVRo+9NN2a3gA1n25wP3n6gQ==\r\n' + '-----END RSA PRIVATE KEY-----\r\n', publicKey: '-----BEGIN PUBLIC KEY-----\r\n' + 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgqu7/2ntXa9rzqiUvDD2\r\n' + 'swStK8w7MFtha/OiwzEDJng7mZUsuy7Neqh5S1Z+nWq7NP51ol//tnNCrWM6Vozr\r\n' + 'JKTAEC2qj3k+bMWnjuTU7sTJHpoZ9wdCqS9q7oOJhqwBxS7M9l8LNA+6I4Qj1bY1\r\n' + 'g2XeZsxEjJfCvILa3yBzztL3CxSFR36FoOo9IpzYlVcE9mqTdJgTwR43ZsFNCRAk\r\n' + 'fSqJjLKy1A2+aDxUcrom2OrLSITICWqz5R1hFIIIB0aprjpz5F2MunciUAhTjUqr\r\n' + 'QPCtw17wmwmaeXZsu0zoq9P/VtKEAxtQkS4tqgnodBzmmgM8YemjkJAVHQzkH8ji\r\n' + 'GQIDAQAB\r\n' + '-----END PUBLIC KEY-----\r\n', certificate: '-----BEGIN CERTIFICATE-----\r\n' + 'MIIECTCCAvGgAwIBAgIBATANBgkqhkiG9w0BAQsFADBpMRQwEgYDVQQDEwtleGFt\r\n' + 'cGxlLm9yZzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMRMwEQYDVQQH\r\n' + 'EwpCbGFja3NidXJnMQ0wCwYDVQQKEwRUZXN0MQ0wCwYDVQQLEwRUZXN0MB4XDTE1\r\n' + 'MTAwOTE3NTc1NloXDTE2MTAwOTE3NTc1NlowaTEUMBIGA1UEAxMLZXhhbXBsZS5v\r\n' + 'cmcxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxh\r\n' + 'Y2tzYnVyZzENMAsGA1UEChMEVGVzdDENMAsGA1UECxMEVGVzdDCCASIwDQYJKoZI\r\n' + 'hvcNAQEBBQADggEPADCCAQoCggEBAIKru/9p7V2va86olLww9rMErSvMOzBbYWvz\r\n' + 'osMxAyZ4O5mVLLsuzXqoeUtWfp1quzT+daJf/7ZzQq1jOlaM6ySkwBAtqo95PmzF\r\n' + 'p47k1O7EyR6aGfcHQqkvau6DiYasAcUuzPZfCzQPuiOEI9W2NYNl3mbMRIyXwryC\r\n' + '2t8gc87S9wsUhUd+haDqPSKc2JVXBPZqk3SYE8EeN2bBTQkQJH0qiYyystQNvmg8\r\n' + 'VHK6Jtjqy0iEyAlqs+UdYRSCCAdGqa46c+RdjLp3IlAIU41Kq0DwrcNe8JsJmnl2\r\n' + 'bLtM6KvT/1bShAMbUJEuLaoJ6HQc5poDPGHpo5CQFR0M5B/I4hkCAwEAAaOBuzCB\r\n' + 'uDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIC9DA7BgNVHSUENDAyBggrBgEFBQcD\r\n' + 'AQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwgwEQYJYIZI\r\n' + 'AYb4QgEBBAQDAgD3MCwGA1UdEQQlMCOGG2h0dHA6Ly9leGFtcGxlLm9yZy93ZWJp\r\n' + 'ZCNtZYcEfwAAATAdBgNVHQ4EFgQUyX839dHHD+pAfU9F5t/rpQaq3LQwDQYJKoZI\r\n' + 'hvcNAQELBQADggEBAGfr9yMwTXoHbZAj/8bRCfKUUg/xIbQY0RtuDwGKBnzVcz7r\r\n' + 'NpocyEBUFvlbsXK4Dwpql41nYPwEpmm486gpWDqSBB0p0jF3HNHihKhCcR0LDQLt\r\n' + 'hBP7SbX76uL4cHoJkbAVbc4FGARCkE7eVZ0sBWUPmLqVh2JmzlC3geq7Obs7HCvq\r\n' + 'eStorsBlDZt27/N+xhvxdUTGJgiTBxk6BrRLGxUeor9TLRpZ2wsoMSnkIcQyooZ4\r\n' + 'iGAZsqUyanWODz0o6R02kSpTA3zx6LssLuLdnxfi1EmHMSM27Lxuw308XzirTxM2\r\n' + '/N0H5AwUc057+HoygLPfddxOfxHGXz4VmEKMcJ8=\r\n' + '-----END CERTIFICATE-----\r\n' }; var _pem_sha512 = { privateKey: '-----BEGIN RSA PRIVATE KEY-----\r\n' + 'MIIEowIBAAKCAQEAmy+xwQpZMYkMWHhw+kh2TDGbG+AF1w6BFVQ6CduEjUzD5d/j\r\n' + 'URtkaeb0RO/uba+J92DMgJJLWlcTe5FpQMb2lxOrNoYP+suWnNxU7QD5vQ4OiJ+i\r\n' + '3nTMly9LMB3BEEea2ZJRpVboJxRBeGl6pKz4obFfoFxqtSww38Cw8h5Nplt+LXR/\r\n' + 'wq8yCpmN9hTE4CSw8iioIqxOZem3sz4//jcMHJ5/aiTjXwseE8eWjaVfvpDESuwQ\r\n' + 'MNjfJYYP0onzEZmTtztyAspsyf0GZBjd1ew2nVCY0cCkQ1+tqYk7H9rjlj1PxduC\r\n' + 'a4aGVKZjIBFnZXhCE23znOgVt9PxFMPUrmHwqwIDAQABAoIBAC68UWMak7wIUxB9\r\n' + 'zUCC/CV8NwNRF1EqDBP5VrVLSAMp4EFliNcPUdFW/a+ZNowP9pPqsgvygwEFAlgP\r\n' + 'dcxNX0wmX0S/YSadk5FQBb+OsKeQCS56LRmjwU2yr4khHNijR+5IU5BguO+z+Pej\r\n' + 'hIz9jq9bdLoduwEu+tUX+fIg0C/OGfxKQrOXIW3hiJDilx2Bt+eyUYrtIxBhwNC9\r\n' + 'jwwMCUFlcbvQSwq+Vx50v2LVjqalJMdMLQiULsF9nPw7EdUJz+aoM4STv7l4miXi\r\n' + 'utkF4xlAl8lnJKOycsFPbqBBaypZoY3O3mKkWtSFRjD4oNW/juBGHTimPWRYgW3V\r\n' + 'Q+IVHpkCgYEA75+vMp2Expq+iCa+UoV48HIVdiCaCk4vRedVe4IHyWxEkaliCHga\r\n' + 'e9wAsxWipDxROv3yoLxlbddnZSD2YaYaIALH/xpSWlcBHZupyq6jNF7R+14Yx155\r\n' + '88iGyoYKNE2VrcVlL164LIqaEB4lxYanhotwqcC5O6IOhpZZ7jSC/H8CgYEApcq9\r\n' + '/G5po1BgYVZ2hdxTqdx8wniWaQNd7EVpogBhJ4KLC+tN42+vBHJT6BQp/PFRWjY5\r\n' + 'fiC1zwI8ufL12F4T8+ZcQVZkHpLjKporYolYmQm/T8wNDwOziYB67Jp9M2EHdei/\r\n' + 'HNo2FUsXRm+Tb1utiQn7AyJ6PHwwJAU1LbtYpdUCgYEAg4R/YiZ2c5MHNC8fkqdT\r\n' + 'Q5U6FkW6hiF3bMSVdF5f67uSvufauI9C6exMLf6X79BzPQ+YlYQRn4H0a9r1n47N\r\n' + 'E/iy0F8gCBlssVV4kZfcV6gbU/3HV9WQ1a6f3JRJEX/rwR5wdNll+HxyJpqFXK6V\r\n' + 'UBFEWsc+Y26EznXDEiycH/0CgYBxwfMqSfhh/ryjDVi18L/XRVq1dVh/JbhEbjxU\r\n' + '1D3VhlUyEHqZHADS5D9+dpd433wakipQyND3AWn5jSPzGlpGeEHE8yovcEo+6Rnr\r\n' + 'uqH4ICAM+M3dB4UhS+8MedR+dI1R8ilv+qoxYhzOT7CyMA2agiaht/53kh7WGFys\r\n' + 'zGe/IQKBgALJnE5CVQLaJgFcWGH2rnD6hWVh1DdV8ockzLg7ulUW0U5gueHWnaWv\r\n' + 'PhP/P0YWF250IWmEm73LCZi3Cv3gBIwvn5pV3GHjMUexTQ3iODsGC8SdL0svnUTc\r\n' + '5/VlSjAKS4Mn9gwutcXX9/Y2AJa4O6S/QfAQeU5aqkk/Fs+31ose\r\n' + '-----END RSA PRIVATE KEY-----\r\n', publicKey: '-----BEGIN PUBLIC KEY-----\r\n' + 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmy+xwQpZMYkMWHhw+kh2\r\n' + 'TDGbG+AF1w6BFVQ6CduEjUzD5d/jURtkaeb0RO/uba+J92DMgJJLWlcTe5FpQMb2\r\n' + 'lxOrNoYP+suWnNxU7QD5vQ4OiJ+i3nTMly9LMB3BEEea2ZJRpVboJxRBeGl6pKz4\r\n' + 'obFfoFxqtSww38Cw8h5Nplt+LXR/wq8yCpmN9hTE4CSw8iioIqxOZem3sz4//jcM\r\n' + 'HJ5/aiTjXwseE8eWjaVfvpDESuwQMNjfJYYP0onzEZmTtztyAspsyf0GZBjd1ew2\r\n' + 'nVCY0cCkQ1+tqYk7H9rjlj1PxduCa4aGVKZjIBFnZXhCE23znOgVt9PxFMPUrmHw\r\n' + 'qwIDAQAB\r\n' + '-----END PUBLIC KEY-----\r\n', certificate: '-----BEGIN CERTIFICATE-----\r\n' + 'MIIECTCCAvGgAwIBAgIBATANBgkqhkiG9w0BAQ0FADBpMRQwEgYDVQQDEwtleGFt\r\n' + 'cGxlLm9yZzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMRMwEQYDVQQH\r\n' + 'EwpCbGFja3NidXJnMQ0wCwYDVQQKEwRUZXN0MQ0wCwYDVQQLEwRUZXN0MB4XDTE1\r\n' + 'MTAwOTE4MDEwOVoXDTE2MTAwOTE4MDEwOVowaTEUMBIGA1UEAxMLZXhhbXBsZS5v\r\n' + 'cmcxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhWaXJnaW5pYTETMBEGA1UEBxMKQmxh\r\n' + 'Y2tzYnVyZzENMAsGA1UEChMEVGVzdDENMAsGA1UECxMEVGVzdDCCASIwDQYJKoZI\r\n' + 'hvcNAQEBBQADggEPADCCAQoCggEBAJsvscEKWTGJDFh4cPpIdkwxmxvgBdcOgRVU\r\n' + 'OgnbhI1Mw+Xf41EbZGnm9ETv7m2vifdgzICSS1pXE3uRaUDG9pcTqzaGD/rLlpzc\r\n' + 'VO0A+b0ODoifot50zJcvSzAdwRBHmtmSUaVW6CcUQXhpeqSs+KGxX6BcarUsMN/A\r\n' + 'sPIeTaZbfi10f8KvMgqZjfYUxOAksPIoqCKsTmXpt7M+P/43DByef2ok418LHhPH\r\n' + 'lo2lX76QxErsEDDY3yWGD9KJ8xGZk7c7cgLKbMn9BmQY3dXsNp1QmNHApENframJ\r\n' + 'Ox/a45Y9T8XbgmuGhlSmYyARZ2V4QhNt85zoFbfT8RTD1K5h8KsCAwEAAaOBuzCB\r\n' + 'uDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIC9DA7BgNVHSUENDAyBggrBgEFBQcD\r\n' + 'AQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwgwEQYJYIZI\r\n' + 'AYb4QgEBBAQDAgD3MCwGA1UdEQQlMCOGG2h0dHA6Ly9leGFtcGxlLm9yZy93ZWJp\r\n' + 'ZCNtZYcEfwAAATAdBgNVHQ4EFgQUaC1StQewfZ4bMUDUsnpzy/4+CZ8wDQYJKoZI\r\n' + 'hvcNAQENBQADggEBAGy58GzpSG3KAv0DILJPWhtxTRvbnd02AWO6fhCdx+siyQ02\r\n' + 'aKgkf1sAS0MGDDMGiwMKvBTz8+8HnfFx6cA7NG7xtuw9m8yb1LeNLbOc3/TCrG/U\r\n' + 'A27ZediP+hCqElB9MtNHyOx/vv+gdKXTFDG4PlykNFmFsGjrA+sA0OtwKRLPQCxp\r\n' + 'rUtGw+cw+xy3O68/unCl86wc8PA5r4uAaQBXdWThpAL0KJI1ky7auUwpsR+aWILJ\r\n' + '0x6a9LOUnCMbbOTN31vRweFxD0qS2J8QMDkfNflvEWmpIZHF4UEoietXk+suP9tc\r\n' + '87rtT63BEY6KcZJJ+oDnKiZuAujmf1iezC+YORs=\r\n' + '-----END CERTIFICATE-----\r\n' }; var _pem_same_subject = [ '-----BEGIN CERTIFICATE-----\r\n' + 'MIIBrDCCARWgAwIBAgIBATANBgkqhkiG9w0BAQUFADAAMB4XDTE2MDgwNDE0NDcw\r\n' + 'MFoXDTE3MDgwNDE0NDcwMFowGTEXMBUGA1UEAxMOQ2VydCBBdXRob3JpdHkwgZ8w\r\n' + 'DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsBaqRGPC6bZh22NMmATSZq6E70SLfN\r\n' + 'esKFOG337k2belUHr9tXU2699p0fJjNgDntNTo+0Sfu5mMa+zAUqJ3PzQcJ2NVY7\r\n' + 'tYPqhDoPPooi8gv5F7EZZzZZ1FfkdHMSJVOwEn2ZAskN7eJyycibKIwRWu1ky8AK\r\n' + 'M6lZvzGgDaORAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgLEMA0G\r\n' + 'CSqGSIb3DQEBBQUAA4GBACYSi4PVsQVBu8vgUwDWNJs6+Qvuo4FtRuQNDg+aOa/O\r\n' + 'MyOQBv3flEHNGrg7BN72tAdmlZLjp/dz87u8AwRNdW0KqF3zYI9Hsni3JDQjC/ga\r\n' + '//Si48IbHpJrApQD7y9wwO4xjZbHQPRQ8BUJZgg57xeQqDe95vnQ62c7Eqdt97e9\r\n' + '-----END CERTIFICATE-----\r\n', '-----BEGIN CERTIFICATE-----\r\n' + 'MIIBrzCCARigAwIBAgIBAjANBgkqhkiG9w0BAQUFADAAMB4XDTE2MDgwNDE0NDcw\r\n' + 'MFoXDTE4MDgwNDE0NDcwMFowGTEXMBUGA1UEAxMOQ2VydCBBdXRob3JpdHkwgZ8w\r\n' + 'DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOepv6vtleShp+A4XwJwqVAoAkEeR3dG\r\n' + '6ogwYTNMTtLMXoYYXPj3UnKSUbK0XiCY/UK1rSC6/jp8OMb9xvVZ5+AH3y7h2FRm\r\n' + 'gNLGGjuBPnfBea6FEuptk+//eheAQ0wl6Wre96zxILSyrPzBy8F91Ht/psO0WXIl\r\n' + 'dfh/XHhBY3D1AgMBAAGjIDAeMA8GA1UdEwQIMAYBAf8CAQIwCwYDVR0PBAQDAgKE\r\n' + 'MA0GCSqGSIb3DQEBBQUAA4GBAIYjbuzf2dANljhEgAWVPeu50OJJYLoV5umRQjXF\r\n' + 'WfXc53ODU0usuHeeH14a63zW1jqfHgc475WEMgMLL/k0FechIuC9AdcDEgzGmBSG\r\n' + 'PDV8nxhU98gpj6I7ewsVk31WDQhFYeSuYJiDiiL47P0BXJLWb+86fFiQklsm5y0h\r\n' + 'Xt0s\r\n' + '-----END CERTIFICATE-----\r\n' ]; var _pem_past_2050 = { privateKey: '-----BEGIN PRIVATE KEY-----\r\n' + 'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtQM1R5VoB8Hrr\r\n' + 'hdL514H+oQN/FSIiHXsdoZlQqUEQ7yUBgC2c7fbq4Wm9AUHBkc/KfUGb9+ZeX6xo\r\n' + '6L06M57QBD8nkSTStNHozlOwjnKu7DnlyW4j3ej9rBZzshLzAvWGZkx5sR1Eyz/2\r\n' + '2Ns9PL+S4h3eiRGpTw3g3geI1wxBv3CCb/LUF5Wa4NWwIU1GP9S6d8MrOb3WGhR3\r\n' + '64ZxajxSeX8R9WLsAo1Qx0dhsJ/UMwIibZ3hA9y1VBma2QyqQMzdY9OYC4oyE646\r\n' + 'WfyJzHscpc6KNiVsWnYDP9+NStQlvaXMwhaPFpyVkLLB0vHho4oMXgEDTCH1iIe4\r\n' + 'YGw01wQ/AgMBAAECggEAdx1wjHfFNEQkHr25WbDDXU9SWhMrjoz6UlsCT6SuaXgh\r\n' + '1zBLK/OnqcEks5+jl/QqCqunahY8OnJI1S/+uX84Fwh0az2tNXjAQPFqNJ8bVgxv\r\n' + 'mf6tTNeLEq04Gn856/4C1E6NEbWly+B5r7tUsHuNsuznYFKY4/DIN+wu/fPsJ17X\r\n' + 'vbZiev6+OID/XCKPYWNRYiszBcmktGM5L+JLcYYPpxFYGFtw+khhUlazx0OmIuDB\r\n' + 'AaePTtyXb1qQNKHv6wy7l+BTBKAlxoQQHMCw5qsnCr9RHed7LJr0kssUbVaseUOg\r\n' + 'KMWtRG0Ms3ovOPWsVFC509gbGal8q+NSwyKd07SlQQKBgQDZX6bwE1H+V7r5GJwz\r\n' + 'EGRLrMUDbbCb2qqZcSn+TCk9hsJ6jeSwz9KjZ2qONcmMl3WY6XAOdTjmJZl20wF9\r\n' + 'GV58pZAoPhLh6tByX9RlUffXz+1KKMP0/5cxmwV8N0RBWrHcmRc6yMwJGZE7qBUh\r\n' + 'JX/77xj9yPoDW+uOSGp+f0nZMQKBgQDMChqQF1cw7iIljzmtOhSnSEiCH7WYCJgp\r\n' + 'um7KEGfFXxbNX07g6pojdjVFFf9uA6tPaiTnwXLc8wI8yiuwt8yPh60QTrcW/E/0\r\n' + '+iQQGkwrFvWybbEuI++K6rOXdNMq7FEU467qN26lzHpagSEn6bXdss8L7AOcGRif\r\n' + '0E/rSXlYbwKBgQDHFAA6vScJzmUxvyVG6ws/90IT6sClbHVzxB1WhX/7llDElvFM\r\n' + 'MXlTJ+KBzacB+LC904VJ6Hes5+CN35/sZ3COrb7B7F+0wi4XocZO6OwYnZhPo9gb\r\n' + 'qH1a9APpCGCdjid4xkhtEPs0llLZlQ2M5uA45ng37Xlz3Bp2m8HUilUi8QKBgQCa\r\n' + 'RpV5F7zciWIWRipVGZJePeBdSz6SOwVan9V/QVJFQTXLiWHp3Fk5sPpsR0rAU1Pn\r\n' + 'kxlehr2j5LZvYmoQj5jDedHYf7weTB7k23IDHu8ysYSLKjeK7K8FuZqbTUERtmdE\r\n' + 'RTePbuRhxq9I2VRJioPxom680/KSx8L/q5GSFRcETwKBgDZhnBZ7+dIKlPAgfwPC\r\n' + 'OCA2kKE+5UxyeAUeojNrSfHGdzF891PX+90D7sPfJi7SJU4E/UOMG/u8wUv5i2/+\r\n' + '/nKOI6NwKB/m0FqpvxamuNJapn9RQ9bC7oz0Rj2Tho90mohwQG4DHF2uO8364Wb+\r\n' + '9Bu1FCWmILPGcJM5iw6TJPA0\r\n' + '-----END PRIVATE KEY-----\r\n', certificate: '-----BEGIN CERTIFICATE-----\r\n' + 'MIIDqjCCApKgAwIBAgIJAJvrXrdlRWTTMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV\r\n' + 'BAYTAlVTMRAwDgYDVQQIDAdWaXJnaW5hMRMwEQYDVQQHDApCbGFja3NidXJnMQ0w\r\n' + 'CwYDVQQKDARUZXN0MQ0wCwYDVQQLDARUZXN0MRQwEgYDVQQDDAtleGFtcGxlLm9y\r\n' + 'ZzAiGA8yMDUwMDIwMTIzMDAyOVoYDzIwNTEwMjAxMjMwMDI5WjBoMQswCQYDVQQG\r\n' + 'EwJVUzEQMA4GA1UECAwHVmlyZ2luYTETMBEGA1UEBwwKQmxhY2tzYnVyZzENMAsG\r\n' + 'A1UECgwEVGVzdDENMAsGA1UECwwEVGVzdDEUMBIGA1UEAwwLZXhhbXBsZS5vcmcw\r\n' + 'ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtQM1R5VoB8HrrhdL514H+\r\n' + 'oQN/FSIiHXsdoZlQqUEQ7yUBgC2c7fbq4Wm9AUHBkc/KfUGb9+ZeX6xo6L06M57Q\r\n' + 'BD8nkSTStNHozlOwjnKu7DnlyW4j3ej9rBZzshLzAvWGZkx5sR1Eyz/22Ns9PL+S\r\n' + '4h3eiRGpTw3g3geI1wxBv3CCb/LUF5Wa4NWwIU1GP9S6d8MrOb3WGhR364ZxajxS\r\n' + 'eX8R9WLsAo1Qx0dhsJ/UMwIibZ3hA9y1VBma2QyqQMzdY9OYC4oyE646WfyJzHsc\r\n' + 'pc6KNiVsWnYDP9+NStQlvaXMwhaPFpyVkLLB0vHho4oMXgEDTCH1iIe4YGw01wQ/\r\n' + 'AgMBAAGjUzBRMB0GA1UdDgQWBBRxifZwjEsDjYgbajBq+e1r4krdwjAfBgNVHSME\r\n' + 'GDAWgBRxifZwjEsDjYgbajBq+e1r4krdwjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG\r\n' + 'SIb3DQEBCwUAA4IBAQB0V8zdJ1WebOvZNwl6WcbzNJRQePPnGp9pAbGuqpLZHvs6\r\n' + 'geAocgmEqleGOsU9GT30MV1vtkR1IY6CWkVPeSiXS43HT8enoYCJX3AZd6ItUrQH\r\n' + '8UonY8UqAmzsGLO+ttO5o6kEY6K0e1QUdmFkOh9Z6M9U3s3DASwrKQ/xFlHQ2mNi\r\n' + 'h7pKaH2+XlDTrCjhO1ip0n4AwG5lgFJpJlVOZ9+Axzc146q/YZqrhXHYU152Wqo/\r\n' + 'mFlygydsKNwWdpK5fwGBZkBR8AsZvNZaQ9Rr3Rr3y5Xz7+aPfLfWF5hW+d11ghuy\r\n' + 'FDeZMUBehXXEJLXrirfmO2KFmy3iKrniJDDa35Lg\r\n' + '-----END CERTIFICATE-----\r\n' }; describe('x509', function() { it('should convert SHA-1 based certificate to/from PEM', function() { var certificate = PKI.certificateFromPem(_pem.certificate); ASSERT.equal(PKI.certificateToPem(certificate), _pem.certificate); }); it('should convert SHA-256 based certificate to/from PEM', function() { var certificate = PKI.certificateFromPem(_pem_sha256.certificate); ASSERT.equal(PKI.certificateToPem(certificate), _pem_sha256.certificate); }); it('should convert certificate not before < 2050 < not after to/from PEM', function() { var certificate = PKI.certificateFromPem(_pem_past_2050.certificate); ASSERT.equal(PKI.certificateToPem(certificate), _pem_past_2050.certificate); }); it('should convert SHA-512 based certificate to/from PEM', function() { var certificate = PKI.certificateFromPem(_pem_sha512.certificate); ASSERT.equal(PKI.certificateToPem(certificate), _pem_sha512.certificate); }); it('should verify SHA-1 based self-signed certificate', function() { var certificate = PKI.certificateFromPem(_pem.certificate); ASSERT.ok(certificate.verify(certificate)); }); it('should verify SHA-256 based self-signed certificate', function() { var certificate = PKI.certificateFromPem(_pem_sha256.certificate); ASSERT.ok(certificate.verify(certificate)); }); it('should verify SHA-512 based self-signed certificate', function() { var certificate = PKI.certificateFromPem(_pem_sha512.certificate); ASSERT.ok(certificate.verify(certificate)); }); it('should verify not before < 2050 < not after self-signed certificate', function() { var certificate = PKI.certificateFromPem(_pem_past_2050.certificate); ASSERT.ok(certificate.verify(certificate)); }); it('should generate a certificate with authorityKeyIdentifier extension', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, extensions: [{ name: 'authorityKeyIdentifier', keyIdentifier: true, authorityCertIssuer: true, serialNumber: true }], serialNumber: '01', subject: attrs, issuer: attrs, isCA: true }); // verify certificate encoding/parsing var pem = PKI.certificateToPem(cert); cert = PKI.certificateFromPem(pem); // verify authorityKeyIdentifier extension var index = findIndex(cert.extensions, {id: '2.5.29.35'}); ASSERT.ok(index !== -1); var ext = cert.extensions[index]; ASSERT.equal(ext.name, 'authorityKeyIdentifier'); ASSERT.equal(ext.value, UTIL.hexToBytes( '3081888014f57563e0c75d6e9b03fafdb2fd72349f23030300a16da46b30693114' + '30120603550403130b6578616d706c652e6f7267310b3009060355040613025553' + '3111300f0603550408130856697267696e6961311330110603550407130a426c61' + '636b7362757267310d300b060355040a130454657374310d300b060355040b1304' + '54657374820101')); // verify certificate chain var caStore = PKI.createCaStore(); caStore.addCertificate(cert); PKI.verifyCertificateChain(caStore, [cert], function(vfd, depth, chain) { ASSERT.equal(vfd, true); ASSERT.ok(cert.verifySubjectKeyIdentifier()); return true; }); }); it('should generate a certificate with cRLDistributionPoints extension', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, extensions: [{ id: '2.5.29.31', altNames: [{ type: 6, value: 'https://test-organisation.com/test-organisation/crl/test_organisation_ca.crl.der' }] }], serialNumber: '01', subject: attrs, issuer: attrs, isCA: true }); // verify certificate encoding/parsing var pem = PKI.certificateToPem(cert); cert = PKI.certificateFromPem(pem); // verify cRLDistributionPoints extension var index = findIndex(cert.extensions, {id: '2.5.29.31'}); ASSERT.ok(index !== -1); var ext = cert.extensions[index]; ASSERT.equal(ext.name, 'cRLDistributionPoints'); ASSERT.equal(ext.value, UTIL.hexToBytes( '30583056a054a052865068747470733a2f2f746573742d6f7267616e6973617469' + '6f6e2e636f6d2f746573742d6f7267616e69736174696f6e2f63726c2f74657374' + '5f6f7267616e69736174696f6e5f63612e63726c2e646572')); // verify certificate chain var caStore = PKI.createCaStore(); caStore.addCertificate(cert); PKI.verifyCertificateChain(caStore, [cert], function(vfd, depth, chain) { ASSERT.equal(vfd, true); ASSERT.ok(cert.verifySubjectKeyIdentifier()); return true; }); }); it('should generate a certificate with nsComment extension', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var dummyTestStr = 'node-forge is awesome'; var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, extensions: [{ name: 'nsComment', comment: dummyTestStr }], serialNumber: '01', subject: attrs, issuer: attrs, isCA: true }); // verify certificate encoding/parsing var pem = PKI.certificateToPem(cert); cert = PKI.certificateFromPem(pem); // verify nsComment extension var index = findIndex(cert.extensions, {id: '2.16.840.1.113730.1.13'}); ASSERT.ok(index !== -1); var ext = cert.extensions[index]; ASSERT.equal(ASN1.fromDer(ext.value).value, dummyTestStr); // verify certificate chain var caStore = PKI.createCaStore(); caStore.addCertificate(cert); PKI.verifyCertificateChain(caStore, [cert], function(vfd, depth, chain) { ASSERT.equal(vfd, true); ASSERT.ok(cert.verifySubjectKeyIdentifier()); return true; }); }); it('should generate a certificate with postalCode attribute', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }, { name: 'postalCode', value: '24060' }]; var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, serialNumber: '01', subject: attrs, issuer: attrs, isCA: true }); var pem = PKI.certificateToPem(cert); cert = PKI.certificateFromPem(pem); var index = findIndex(cert.subject.attributes, {type: '2.5.4.17'}); ASSERT.ok(index !== -1); var attribute = cert.subject.attributes[index]; ASSERT.equal(attribute.name, 'postalCode'); ASSERT.equal(attribute.value, '24060'); }); it('should generate a certificate with businessCategory attribute', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }, { name: 'businessCategory', value: 'Test Organization' }]; var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, serialNumber: '01', subject: attrs, issuer: attrs, isCA: true }); var pem = PKI.certificateToPem(cert); cert = PKI.certificateFromPem(pem); var index = findIndex(cert.subject.attributes, {type: '2.5.4.15'}); ASSERT.ok(index !== -1); var attribute = cert.subject.attributes[index]; ASSERT.equal(attribute.name, 'businessCategory'); ASSERT.equal(attribute.value, 'Test Organization'); }); it('should generate a certificate with streetAddress attribute', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }, { name: 'streetAddress', value: 'Test Avenue' }]; var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, serialNumber: '01', subject: attrs, issuer: attrs, isCA: true }); var pem = PKI.certificateToPem(cert); cert = PKI.certificateFromPem(pem); var index = findIndex(cert.subject.attributes, {type: '2.5.4.9'}); ASSERT.ok(index !== -1); var attribute = cert.subject.attributes[index]; ASSERT.equal(attribute.name, 'streetAddress'); ASSERT.equal(attribute.value, 'Test Avenue'); }); it('should generate a certificate with jurisdictionOfIncorporationStateOrProvinceName attribute', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }, { name: 'jurisdictionOfIncorporationStateOrProvinceName', value: 'Delaware' }]; var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, serialNumber: '01', subject: attrs, issuer: attrs, isCA: true }); var pem = PKI.certificateToPem(cert); cert = PKI.certificateFromPem(pem); var index = findIndex(cert.subject.attributes, {type: '1.3.6.1.4.1.311.60.2.1.2'}); ASSERT.ok(index !== -1); var attribute = cert.subject.attributes[index]; ASSERT.equal(attribute.name, 'jurisdictionOfIncorporationStateOrProvinceName'); ASSERT.equal(attribute.value, 'Delaware'); }); it('should generate a certificate with jurisdictionOfIncorporationCountryName attribute', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }, { name: 'jurisdictionOfIncorporationCountryName', value: 'US' }]; var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, serialNumber: '01', subject: attrs, issuer: attrs, isCA: true }); var pem = PKI.certificateToPem(cert); cert = PKI.certificateFromPem(pem); var index = findIndex(cert.subject.attributes, {type: '1.3.6.1.4.1.311.60.2.1.3'}); ASSERT.ok(index !== -1); var attribute = cert.subject.attributes[index]; ASSERT.equal(attribute.name, 'jurisdictionOfIncorporationCountryName'); ASSERT.equal(attribute.value, 'US'); }); it('should generate and verify a self-signed certificate', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, serialNumber: '01', subject: attrs, issuer: attrs, isCA: true }); var pem = PKI.certificateToPem(cert); cert = PKI.certificateFromPem(pem); // verify certificate chain var caStore = PKI.createCaStore(); caStore.addCertificate(cert); PKI.verifyCertificateChain(caStore, [cert], function(vfd, depth, chain) { ASSERT.equal(vfd, true); ASSERT.ok(cert.verifySubjectKeyIdentifier()); return true; }); }); it('should generate a self-signed certificate after 2050', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var notBefore = new Date('2050-02-02'); var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, serialNumber: '01', subject: attrs, issuer: attrs, isCA: true, notBefore: notBefore }); var pem = PKI.certificateToPem(cert); cert = PKI.certificateFromPem(pem); var notAfter = new Date('2051-02-02'); ASSERT.equal(cert.validity.notBefore.toString(), notBefore.toString()); ASSERT.equal(cert.validity.notAfter.toString(), notAfter.toString()); }); it('should generate and fail to verify a self-signed certificate that is not in the CA store', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, serialNumber: '01', subject: attrs, issuer: attrs, isCA: true }); var pem = PKI.certificateToPem(cert); cert = PKI.certificateFromPem(pem); // verify certificate chain var caStore = PKI.createCaStore(); PKI.verifyCertificateChain(caStore, [cert], function(vfd, depth, chain) { ASSERT.equal(vfd, PKI.certificateError.unknown_ca); return true; }); }); it('should verify certificate chain ending with intermediate certificate from CA store', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var entity = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var intermediate = [{ name: 'commonName', value: 'intermediate' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var root = [{ name: 'commonName', value: 'root' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var intermediateCert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, serialNumber: '01', subject: intermediate, issuer: root, isCA: true }); var entityCert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, serialNumber: '01', subject: entity, issuer: intermediate, isCA: false }); // verify certificate chain var caStore = PKI.createCaStore(); caStore.addCertificate(intermediateCert); var chain = [entityCert, intermediateCert]; PKI.verifyCertificateChain(caStore, chain, function(vfd, depth, chain) { ASSERT.equal(vfd, true); return true; }); }); it('should fail to verify certificate chain ending with non-CA intermediate certificate from CA store', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var entity = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var intermediate = [{ name: 'commonName', value: 'intermediate' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var root = [{ name: 'commonName', value: 'root' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var intermediateCert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, serialNumber: '01', subject: intermediate, issuer: root, isCA: false }); var entityCert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, serialNumber: '01', subject: entity, issuer: intermediate, isCA: false }); // verify certificate chain var caStore = PKI.createCaStore(); caStore.addCertificate(intermediateCert); var chain = [entityCert, intermediateCert]; PKI.verifyCertificateChain(caStore, chain, function(vfd, depth, chain) { if(depth === 0) { ASSERT.equal(vfd, true); } else { ASSERT.equal(vfd, PKI.certificateError.bad_certificate); } return true; }); }); it('should verify based on a custom specified validity date', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, extensions: [{ name: 'authorityKeyIdentifier', keyIdentifier: true, authorityCertIssuer: true, serialNumber: true }], serialNumber: '01', subject: attrs, issuer: attrs, isCA: true }); var caStore = PKI.createCaStore(); caStore.addCertificate(cert); var verifyDate = new Date(); PKI.verifyCertificateChain(caStore, [cert], { validityCheckDate: verifyDate, verify: function(vfd, depth, chain) { ASSERT.equal(vfd, true); return true; } }); verifyDate = new Date(); verifyDate.setFullYear(verifyDate.getFullYear() + 2); PKI.verifyCertificateChain(caStore, [cert], { validityCheckDate: verifyDate, verify: function(vfd, depth, chain) { ASSERT.equal(vfd, 'forge.pki.CertificateExpired'); return true; } }); verifyDate = new Date(); verifyDate.setFullYear(verifyDate.getFullYear() - 1); PKI.verifyCertificateChain(caStore, [cert], { validityCheckDate: verifyDate, verify: function(vfd, depth, chain) { ASSERT.equal(vfd, 'forge.pki.CertificateExpired'); return true; } }); }); it('should not verify the validity period if null is passed as validityCheckDate', function() { var keys = { privateKey: PKI.privateKeyFromPem(_pem.privateKey), publicKey: PKI.publicKeyFromPem(_pem.publicKey) }; var attrs = [{ name: 'commonName', value: 'example.org' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Test' }, { shortName: 'OU', value: 'Test' }]; var pastDate = new Date(); pastDate.setFullYear(pastDate.getFullYear() - 1); var cert = createCertificate({ publicKey: keys.publicKey, signingKey: keys.privateKey, extensions: [{ name: 'authorityKeyIdentifier', keyIdentifier: true, authorityCertIssuer: true, serialNumber: true }], serialNumber: '01', subject: attrs, issuer: attrs, isCA: true, notBefore: pastDate, notAfter: pastDate }); var caStore = PKI.createCaStore(); caStore.addCertificate(cert); PKI.verifyCertificateChain(caStore, [cert], { verify: function(vfd, depth, chain) { ASSERT.equal(vfd, 'forge.pki.CertificateExpired'); return true; } }); PKI.verifyCertificateChain(caStore, [cert], { validityCheckDate: null, verify: function(vfd, depth, chain) { ASSERT.equal(vfd, true); return true; } }); }); it('should verify certificate with sha1WithRSAEncryption signature', function() { var certPem = '-----BEGIN CERTIFICATE-----\r\n' + 'MIIDZDCCAs2gAwIBAgIKQ8fjjgAAAABh3jANBgkqhkiG9w0BAQUFADBGMQswCQYD\r\n' + 'VQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZR29vZ2xlIElu\r\n' + 'dGVybmV0IEF1dGhvcml0eTAeFw0xMjA2MjcxMzU5MTZaFw0xMzA2MDcxOTQzMjda\r\n' + 'MGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1N\r\n' + 'b3VudGFpbiBWaWV3MRMwEQYDVQQKEwpHb29nbGUgSW5jMRYwFAYDVQQDEw13d3cu\r\n' + 'Z29vZ2xlLmRlMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCw2Hw3vNy5QMSd\r\n' + '0/iMCS8lwZk9lnEk2NmrJt6vGJfRGlBprtHp5lpMFMoi+x8m8EwGVxXHGp7hLyN/\r\n' + 'gXuUjL7/DY9fxxx9l77D+sDZz7jfUfWmhS03Ra1FbT6myF8miVZFChJ8XgWzioJY\r\n' + 'gyNdRUC9149yrXdPWrSmSVaT0+tUCwIDAQABo4IBNjCCATIwHQYDVR0lBBYwFAYI\r\n' + 'KwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBTiQGhrO3785rMPIKZ/zQEl5RyS\r\n' + '0TAfBgNVHSMEGDAWgBS/wDDr9UMRPme6npH7/Gra42sSJDBbBgNVHR8EVDBSMFCg\r\n' + 'TqBMhkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2dsZUludGVybmV0QXV0aG9y\r\n' + 'aXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNybDBmBggrBgEFBQcBAQRaMFgw\r\n' + 'VgYIKwYBBQUHMAKGSmh0dHA6Ly93d3cuZ3N0YXRpYy5jb20vR29vZ2xlSW50ZXJu\r\n' + 'ZXRBdXRob3JpdHkvR29vZ2xlSW50ZXJuZXRBdXRob3JpdHkuY3J0MAwGA1UdEwEB\r\n' + '/wQCMAAwDQYJKoZIhvcNAQEFBQADgYEAVJ0qt/MBvHEPuWHeH51756qy+lBNygLA\r\n' + 'Xp5Gq+xHUTOzRty61BR05zv142hYAGWvpvnEOJ/DI7V3QlXK8a6dQ+du97obQJJx\r\n' + '7ekqtfxVzmlSb23halYSoXmWgP8Tq0VUDsgsSLE7fS8JuO1soXUVKj1/6w189HL6\r\n' + 'LsngXwZSuL0=\r\n' + '-----END CERTIFICATE-----\r\n'; var issuerPem = '-----BEGIN CERTIFICATE-----\r\n' + 'MIICsDCCAhmgAwIBAgIDC2dxMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT\r\n' + 'MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0\r\n' + 'aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDkwNjA4MjA0MzI3WhcNMTMwNjA3MTk0MzI3\r\n' + 'WjBGMQswCQYDVQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzEiMCAGA1UEAxMZ\r\n' + 'R29vZ2xlIEludGVybmV0IEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw\r\n' + 'gYkCgYEAye23pIucV+eEPkB9hPSP0XFjU5nneXQUr0SZMyCSjXvlKAy6rWxJfoNf\r\n' + 'NFlOCnowzdDXxFdF7dWq1nMmzq0yE7jXDx07393cCDaob1FEm8rWIFJztyaHNWrb\r\n' + 'qeXUWaUr/GcZOfqTGBhs3t0lig4zFEfC7wFQeeT9adGnwKziV28CAwEAAaOBozCB\r\n' + 'oDAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFL/AMOv1QxE+Z7qekfv8atrjaxIk\r\n' + 'MB8GA1UdIwQYMBaAFEjmaPkr0rKV10fYIyAQTzOYkJ/UMBIGA1UdEwEB/wQIMAYB\r\n' + 'Af8CAQAwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20v\r\n' + 'Y3Jscy9zZWN1cmVjYS5jcmwwDQYJKoZIhvcNAQEFBQADgYEAuIojxkiWsRF8YHde\r\n' + 'BZqrocb6ghwYB8TrgbCoZutJqOkM0ymt9e8kTP3kS8p/XmOrmSfLnzYhLLkQYGfN\r\n' + '0rTw8Ktx5YtaiScRhKqOv5nwnQkhClIZmloJ0pC3+gz4fniisIWvXEyZ2VxVKfml\r\n' + 'UUIuOss4jHg7y/j7lYe8vJD5UDI=\r\n' + '-----END CERTIFICATE-----\r\n'; var cert = PKI.certificateFromPem(certPem, true); var issuer = PKI.certificateFromPem(issuerPem); ASSERT.ok(issuer.verify(cert)); }); it('should verify certificate with sha256WithRSAEncryption signature', function() { var certPem = '-----BEGIN CERTIFICATE-----\r\n' + 'MIIDuzCCAqOgAwIBAgIEO5vZjDANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJE\r\n' + 'RTEPMA0GA1UEChMGRWxzdGVyMQswCQYDVQQLEwJDQTEZMBcGA1UEAxMQRWxzdGVy\r\n' + 'U29mdFRlc3RDQTAeFw0xMDA5MTUwNTM4MjRaFw0xMzA5MTUwNTM4MjRaMCsxFDAS\r\n' + 'BgNVBAUTCzEwMDIzMTQ5OTRDMRMwEQYDVQQDEwoxMDAyMzE0OTk0MIGfMA0GCSqG\r\n' + 'SIb3DQEBAQUAA4GNADCBiQKBgQCLPqjbwjsugzw6+qwwm/pdzDwk7ASIsBYJ17GT\r\n' + 'qyT0zCnYmdDDGWsYc+xxFVVIi8xBt6Mlq8Rwj+02UJhY9qm6zRA9MqFZC3ih+HoW\r\n' + 'xq7H8N2d10N0rX6h5PSjkF5fU5ugncZmppsRGJ9DNXgwjpf/CsH2rqThUzK4xfrq\r\n' + 'jpDS/wIDAQABo4IBTjCCAUowDgYDVR0PAQH/BAQDAgUgMAwGA1UdEwEB/wQCMAAw\r\n' + 'HQYDVR0OBBYEFF1h7H37OQivS57GD8+nK6VsgMPTMIGXBgNVHR8EgY8wgYwwgYmg\r\n' + 'gYaggYOGgYBsZGFwOi8vMTkyLjE2OC42LjI0OjM4OS9sJTNkQ0ElMjBaZXJ0aWZp\r\n' + 'a2F0ZSxvdSUzZENBLGNuJTNkRWxzdGVyU29mdFRlc3RDQSxkYyUzZHdpZXNlbCxk\r\n' + 'YyUzZGVsc3RlcixkYyUzZGRlPz9iYXNlPyhvYmplY3RDbGFzcz0qKTBxBgNVHSME\r\n' + 'ajBogBRBILMYmlZu//pj3wjDe2UPkq7jk6FKpEgwRjELMAkGA1UEBhMCREUxDzAN\r\n' + 'BgNVBAoTBkVsc3RlcjEPMA0GA1UECxMGUm9vdENBMRUwEwYDVQQDEwxFbHN0ZXJS\r\n' + 'b290Q0GCBDuayikwDQYJKoZIhvcNAQELBQADggEBAK8Z1+/VNyU5w/EiyhFH5aRE\r\n' + 'Mzxo0DahqKEm4pW5haBgKubJwZGs+CrBZR70TPbZGgJd36eyMgeXb/06lBnxewii\r\n' + 'I/aY6wMTviQTpqFnz5m0Le8UhH+hY1bqNG/vf6J+1gbOSrZyhAUV+MDJbL/OkzX4\r\n' + 'voVAfUBqSODod0f5wCW2RhvBmB9E62baP6qizdxyPA4iV16H4C0etd/7coLX6NZC\r\n' + 'oz3Yu0IRTQCH+YrpfIbxGb0grNhtCTfFpa287fuzu8mIEvLNr8GibhBXmQg7iJ+y\r\n' + 'q0VIyZLY8k6jEPrUB5Iv5ouSR19Dda/2+xJPlT/bosuNcErEuk/yKAHWAzwm1wQ=\r\n' + '-----END CERTIFICATE-----\r\n'; var issuerPem = '-----BEGIN CERTIFICATE-----\r\n' + 'MIIESjCCAzKgAwIBAgIEO5rKKTANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQGEwJE\r\n' + 'RTEPMA0GA1UEChMGRWxzdGVyMQ8wDQYDVQQLEwZSb290Q0ExFTATBgNVBAMTDEVs\r\n' + 'c3RlclJvb3RDQTAeFw0wOTA3MjgwODE5MTFaFw0xNDA3MjgwODE5MTFaMEYxCzAJ\r\n' + 'BgNVBAYTAkRFMQ8wDQYDVQQKEwZFbHN0ZXIxCzAJBgNVBAsTAkNBMRkwFwYDVQQD\r\n' + 'ExBFbHN0ZXJTb2Z0VGVzdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\r\n' + 'AQEAv5uoKLnxXQe75iqwqgyt3H6MDAx/wvUVs26+2+yHpEUb/2gA3L8E+NChSb9E\r\n' + 'aNgxxoac3Yhvxzq2mPpih3vkY7Xw512Tm8l/OPbT8kbmBJmYZneFALXHytAIZiEf\r\n' + 'e0ZYNKAlClFIgNP5bE9UjTqVEEoSiUhpTubM6c5xEYVznnwPBoYQ0ari7RTDYnME\r\n' + 'HK4vMfoeBeWHYPiEygNHnGUG8d3merRC/lQASUtL6ikmLWKCKHfyit5ACzPNKAtw\r\n' + 'IzHAzD5ek0BpcUTci8hUsKz2ZvmoZcjPyj63veQuMYS5cTMgr3bfz9uz1xuoEDsb\r\n' + 'Sv9rQX9Iw3N7yMpxTDJTqGKhYwIDAQABo4IBPjCCATowDgYDVR0PAQH/BAQDAgEG\r\n' + 'MBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEEgsxiaVm7/+mPfCMN7ZQ+S\r\n' + 'ruOTMIGXBgNVHR8EgY8wgYwwgYmggYaggYOGgYBsZGFwOi8vMTkyLjE2OC42LjI0\r\n' + 'OjM4OS9sJTNkQ0ElMjBaZXJ0aWZpa2F0ZSxvdSUzZFJvb3RDQSxjbiUzZEVsc3Rl\r\n' + 'clJvb3RDQSxkYyUzZHdpZXNlbCxkYyUzZGVsc3RlcixkYyUzZGRlPz9iYXNlPyhv\r\n' + 'YmplY3RDbGFzcz0qKTBbBgNVHSMEVDBSoUqkSDBGMQswCQYDVQQGEwJERTEPMA0G\r\n' + 'A1UEChMGRWxzdGVyMQ8wDQYDVQQLEwZSb290Q0ExFTATBgNVBAMTDEVsc3RlclJv\r