@sphereon/ssi-sdk-ext.kms-local 0.10.2-next.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +18 -0
- package/dist/SphereonKeyManagementSystem.d.ts +22 -0
- package/dist/SphereonKeyManagementSystem.d.ts.map +1 -0
- package/dist/SphereonKeyManagementSystem.js +210 -0
- package/dist/SphereonKeyManagementSystem.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/ssi-sdk-ext.kms-local.d.ts +39 -0
- package/dist/tsdoc-metadata.json +11 -0
- package/dist/x509/digest-methods.d.ts +7 -0
- package/dist/x509/digest-methods.d.ts.map +1 -0
- package/dist/x509/digest-methods.js +95 -0
- package/dist/x509/digest-methods.js.map +1 -0
- package/dist/x509/rsa-key.d.ts +11 -0
- package/dist/x509/rsa-key.d.ts.map +1 -0
- package/dist/x509/rsa-key.js +83 -0
- package/dist/x509/rsa-key.js.map +1 -0
- package/dist/x509/rsa-signer.d.ts +24 -0
- package/dist/x509/rsa-signer.d.ts.map +1 -0
- package/dist/x509/rsa-signer.js +99 -0
- package/dist/x509/rsa-signer.js.map +1 -0
- package/package.json +44 -0
- package/src/SphereonKeyManagementSystem.ts +197 -0
- package/src/__tests__/bls-kms-local.test.ts +70 -0
- package/src/__tests__/certs.ts +127 -0
- package/src/__tests__/rsa.test.ts +156 -0
- package/src/index.ts +6 -0
- package/src/x509/digest-methods.ts +74 -0
- package/src/x509/rsa-key.ts +61 -0
- package/src/x509/rsa-signer.ts +67 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export const PEM_PRIV_KEY =
|
|
2
|
+
'-----BEGIN PRIVATE KEY-----\n' +
|
|
3
|
+
'MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDV6x+HCJFKkVgb\n' +
|
|
4
|
+
'eUWy9iCWOFm1J5vNnbODDMasHPjp8m7Pj2zBqdkUsJn62cTENgAI0b6VB/iTtqwy\n' +
|
|
5
|
+
'pdYUQxTajEhnUm/9FeQf8vj8C34OI880PehgeviCQrClWrLzjDccEvoQVSKtz8A1\n' +
|
|
6
|
+
'Yzc3Squw8uQfFKVqPCDKy6nVjhTeDHj9txBJTfomH+WYHpD3sumRXu3GB5xZQGwC\n' +
|
|
7
|
+
'6H23craJpV1Rw3D/z7nFlqlg9AQZwSnjvI+LE4nZKZemhHaJOm9krhk3IXcnGopC\n' +
|
|
8
|
+
'DakYmpVtWi+2FLB3FCQ6oXbWhtB3oiIly8OacdLEujoOIcEZgRjEk7zc9KRNjdfK\n' +
|
|
9
|
+
'HvJkwCRTAgMBAAECggEBAJV2aFrSs6EkGClp/DbkHTSYPqWB/SwWyXwBCzbqL0hW\n' +
|
|
10
|
+
'KPJAxb4yTAhWs98/FGn7SN7gnYZHQXkDoyDoGcGidQmWBmiagsCT8QYZn7mK1hJP\n' +
|
|
11
|
+
'FtDriFcQ1F0+92kxC+N6zm6BG9MZiNdkVml23vd05q0FqDnHFSQ6yramwg0B7raN\n' +
|
|
12
|
+
'PQ7sg7CY087aMeyjKkISG1kin0JJdfRwYQBtdmpsvhjVhXteBqiyXhyg/Xkrt6+5\n' +
|
|
13
|
+
'K4PH1BgEgvg7vODPVfs7ZApyzZPeD0Gf5+Chxg1JVkGvxc1pLAveTHH94NNQHlts\n' +
|
|
14
|
+
'+KooVRRhPB5zmdIJGOODp9qjcK+Jjd4kJC80hgBuUDECgYEA9JjPr8ewBGgtaQKm\n' +
|
|
15
|
+
'e59+MWBRqzdcNRk+P5MH1TBB99jhwjhQNWGvUs0j4f9+1sULMun/OL+v0Osr2L1f\n' +
|
|
16
|
+
'TDDEnSEBk4wEiv8QX+PmbGCs3qBp5c75V1J3q3N2Nsd64NCLv1YIP+U9lnsMapUy\n' +
|
|
17
|
+
'w6RN8HQq1Y8DDo2G5VREsWYhSY0CgYEA3+Qsf1mNB2Y6fbVi2EDSy5tdkCyPKFUY\n' +
|
|
18
|
+
'Sy58VVaoA8td8StjUk0FhHYwaoo63GFOuvtJTF/MRl8IMbgXQFBhKXsVqVVl1KS9\n' +
|
|
19
|
+
'gg+maVlZDDLvmSlinF8Wo46FkdVeBW/PWXrbb5l7v9yu9eqWkqvXNzelkRy11Z7U\n' +
|
|
20
|
+
'Sw4NCI5sfV8CgYBEnc29gSZWxibfC5hKm96Z2WxvvLMITlGRIh0TaFtJPTVv975A\n' +
|
|
21
|
+
'i2vUranAT510gIh4uv4XHGclE6QURGPEivXNIqI/kwr/NziPve45PxGfzp6Gkn6O\n' +
|
|
22
|
+
'SZs6pMRn76QAB2D8xxS/X/7cBR7hk4NPMPuQVfZiPKFd5sQN94rhvUXfTQKBgQC5\n' +
|
|
23
|
+
'xA+rprjeP9MeRKb7+WUtrP6HxoENnPVoQ+zDvf/wDggnN7HUMrX2Pz5S19iYzGBP\n' +
|
|
24
|
+
'wnoB1aafaPBamH0qTscfbNH/Sy0Pr5TR2nxgAtNgzM6CTZVVW4xkLrfi1Z+KcUgg\n' +
|
|
25
|
+
'3VA/G6FTAx9kSb2fetc6KIDGk4TH91373G+x/sJDjwKBgQDfMzwxV+XoYfwbtNuR\n' +
|
|
26
|
+
'DGKLXcv/SB8O0DbEp/KlF/85DLDFy7RPwCNRc44N9007U0XEjnKMus0XUqwE+0go\n' +
|
|
27
|
+
'KcMDfw3m+PjempOVqnQLB6JgiHfrVwQGq6JVY90fGH9rnAs+muxxSHxWmZqRQ2oO\n' +
|
|
28
|
+
'dtonyvREV44ngrwe4nGK8O5N4A==\n' +
|
|
29
|
+
'-----END PRIVATE KEY-----'
|
|
30
|
+
|
|
31
|
+
export const PEM_CERT =
|
|
32
|
+
'-----BEGIN CERTIFICATE-----\n' +
|
|
33
|
+
'MIIFRDCCBCygAwIBAgISA9XiEfV2I/bCdv4X1NgKQijKMA0GCSqGSIb3DQEBCwUA\n' +
|
|
34
|
+
'MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD\n' +
|
|
35
|
+
'EwJSMzAeFw0yMzAxMDIxMTU0NTlaFw0yMzA0MDIxMTU0NThaMCoxKDAmBgNVBAMT\n' +
|
|
36
|
+
'H2Y4MjUtODctMjEzLTI0MS0yNTEuZXUubmdyb2suaW8wggEiMA0GCSqGSIb3DQEB\n' +
|
|
37
|
+
'AQUAA4IBDwAwggEKAoIBAQDV6x+HCJFKkVgbeUWy9iCWOFm1J5vNnbODDMasHPjp\n' +
|
|
38
|
+
'8m7Pj2zBqdkUsJn62cTENgAI0b6VB/iTtqwypdYUQxTajEhnUm/9FeQf8vj8C34O\n' +
|
|
39
|
+
'I880PehgeviCQrClWrLzjDccEvoQVSKtz8A1Yzc3Squw8uQfFKVqPCDKy6nVjhTe\n' +
|
|
40
|
+
'DHj9txBJTfomH+WYHpD3sumRXu3GB5xZQGwC6H23craJpV1Rw3D/z7nFlqlg9AQZ\n' +
|
|
41
|
+
'wSnjvI+LE4nZKZemhHaJOm9krhk3IXcnGopCDakYmpVtWi+2FLB3FCQ6oXbWhtB3\n' +
|
|
42
|
+
'oiIly8OacdLEujoOIcEZgRjEk7zc9KRNjdfKHvJkwCRTAgMBAAGjggJaMIICVjAO\n' +
|
|
43
|
+
'BgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwG\n' +
|
|
44
|
+
'A1UdEwEB/wQCMAAwHQYDVR0OBBYEFLNsFqhuvQ7AVtoFYdt3H4TNc88rMB8GA1Ud\n' +
|
|
45
|
+
'IwQYMBaAFBQusxe3WFbLrlAJQOYfr52LFMLGMFUGCCsGAQUFBwEBBEkwRzAhBggr\n' +
|
|
46
|
+
'BgEFBQcwAYYVaHR0cDovL3IzLm8ubGVuY3Iub3JnMCIGCCsGAQUFBzAChhZodHRw\n' +
|
|
47
|
+
'Oi8vcjMuaS5sZW5jci5vcmcvMCoGA1UdEQQjMCGCH2Y4MjUtODctMjEzLTI0MS0y\n' +
|
|
48
|
+
'NTEuZXUubmdyb2suaW8wTAYDVR0gBEUwQzAIBgZngQwBAgEwNwYLKwYBBAGC3xMB\n' +
|
|
49
|
+
'AQEwKDAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwggEE\n' +
|
|
50
|
+
'BgorBgEEAdZ5AgQCBIH1BIHyAPAAdgC3Pvsk35xNunXyOcW6WPRsXfxCz3qfNcSe\n' +
|
|
51
|
+
'HQmBJe20mQAAAYVyjKwhAAAEAwBHMEUCIF1xp237jcAJFNNg/u4AglOW57CGcESp\n' +
|
|
52
|
+
'vyFOzQRYyrtxAiEAtJPM85K04y6LJEn6o9+XB9SXKzzDXTYT/0rhUav0Hf8AdgCt\n' +
|
|
53
|
+
'9776fP8QyIudPZwePhhqtGcpXc+xDCTKhYY069yCigAAAYVyjKxLAAAEAwBHMEUC\n' +
|
|
54
|
+
'IQCI3/3G0nuoXtrjY8v/FS18hSFQiMQyAdZ7AJP/wWafKwIgZQYm/17cF/bAAUmV\n' +
|
|
55
|
+
'cJVRNBm9uOW5/h7+bq+KcRbb5TMwDQYJKoZIhvcNAQELBQADggEBACiqjMGRHKpa\n' +
|
|
56
|
+
's4cqhyK4XWzFCjqS1KOyGv8vtC5EAC1ywUiSB7eYEev3Iba3SpQf6Ur3jD+ER5+I\n' +
|
|
57
|
+
'G+Xk15BtheslWb0oV3jCxxSCLxHObuF01fOP9WnA18hwoOW6PdjYl2KwluBfpsOu\n' +
|
|
58
|
+
'MlXZPl7k/X8JqJCHMyEwn37OSwflkiu9ansM8Q9Dnm3+nl66HFYUZzp5l5lS60v2\n' +
|
|
59
|
+
'i4cusxxVWy32k0Qa7cyu+wdTk9KEoEzpnuDvfCdlz+fuSGf8usPtFyPEM2MFQyVN\n' +
|
|
60
|
+
'9V2icZrMwwIBxn9YvTndy6NpYlcXotSbb64ko4ss68I6f8Rf78vjmeFHaac8wz+k\n' +
|
|
61
|
+
'1zNHGxNMFnI=\n' +
|
|
62
|
+
'-----END CERTIFICATE-----'
|
|
63
|
+
export const PEM_CHAIN =
|
|
64
|
+
'-----BEGIN CERTIFICATE-----\n' +
|
|
65
|
+
'MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw\n' +
|
|
66
|
+
'TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\n' +
|
|
67
|
+
'cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw\n' +
|
|
68
|
+
'WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg\n' +
|
|
69
|
+
'RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n' +
|
|
70
|
+
'AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP\n' +
|
|
71
|
+
'R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx\n' +
|
|
72
|
+
'sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm\n' +
|
|
73
|
+
'NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg\n' +
|
|
74
|
+
'Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG\n' +
|
|
75
|
+
'/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC\n' +
|
|
76
|
+
'AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB\n' +
|
|
77
|
+
'Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA\n' +
|
|
78
|
+
'FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw\n' +
|
|
79
|
+
'AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw\n' +
|
|
80
|
+
'Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB\n' +
|
|
81
|
+
'gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W\n' +
|
|
82
|
+
'PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl\n' +
|
|
83
|
+
'ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz\n' +
|
|
84
|
+
'CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm\n' +
|
|
85
|
+
'lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4\n' +
|
|
86
|
+
'avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2\n' +
|
|
87
|
+
'yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O\n' +
|
|
88
|
+
'yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids\n' +
|
|
89
|
+
'hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+\n' +
|
|
90
|
+
'HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv\n' +
|
|
91
|
+
'MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX\n' +
|
|
92
|
+
'nLRbwHOoq7hHwg==\n' +
|
|
93
|
+
'-----END CERTIFICATE-----\n' +
|
|
94
|
+
'\n' +
|
|
95
|
+
'-----BEGIN CERTIFICATE-----\n' +
|
|
96
|
+
'MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/\n' +
|
|
97
|
+
'MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n' +
|
|
98
|
+
'DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow\n' +
|
|
99
|
+
'TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\n' +
|
|
100
|
+
'cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB\n' +
|
|
101
|
+
'AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC\n' +
|
|
102
|
+
'ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL\n' +
|
|
103
|
+
'wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D\n' +
|
|
104
|
+
'LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK\n' +
|
|
105
|
+
'4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5\n' +
|
|
106
|
+
'bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y\n' +
|
|
107
|
+
'sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ\n' +
|
|
108
|
+
'Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4\n' +
|
|
109
|
+
'FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc\n' +
|
|
110
|
+
'SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql\n' +
|
|
111
|
+
'PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND\n' +
|
|
112
|
+
'TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw\n' +
|
|
113
|
+
'SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1\n' +
|
|
114
|
+
'c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx\n' +
|
|
115
|
+
'+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB\n' +
|
|
116
|
+
'ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu\n' +
|
|
117
|
+
'b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E\n' +
|
|
118
|
+
'U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu\n' +
|
|
119
|
+
'MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC\n' +
|
|
120
|
+
'5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW\n' +
|
|
121
|
+
'9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG\n' +
|
|
122
|
+
'WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O\n' +
|
|
123
|
+
'he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC\n' +
|
|
124
|
+
'Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5\n' +
|
|
125
|
+
'-----END CERTIFICATE-----'
|
|
126
|
+
|
|
127
|
+
export const PEM_FULL_CHAIN = `${PEM_CERT}\n${PEM_CHAIN}`
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import JSEncrypt from '@sphereon/jsencrypt'
|
|
2
|
+
import { PEM_CERT, PEM_CHAIN, PEM_FULL_CHAIN, PEM_PRIV_KEY } from './certs'
|
|
3
|
+
import { digestMethodParams } from '../x509/digest-methods'
|
|
4
|
+
import { SphereonKeyManagementSystem } from '../SphereonKeyManagementSystem'
|
|
5
|
+
import { MemoryPrivateKeyStore } from '@veramo/key-manager'
|
|
6
|
+
import * as u8a from 'uint8arrays'
|
|
7
|
+
import {
|
|
8
|
+
pemCertChainTox5c,
|
|
9
|
+
PEMToJwk,
|
|
10
|
+
privateKeyHexFromPEM,
|
|
11
|
+
publicKeyHexFromPEM,
|
|
12
|
+
toKeyObject,
|
|
13
|
+
X509Opts,
|
|
14
|
+
x5cToPemCertChain,
|
|
15
|
+
} from '@sphereon/ssi-sdk-did-utils'
|
|
16
|
+
import { RSASigner } from '../x509/rsa-signer'
|
|
17
|
+
|
|
18
|
+
describe('X509 PEMs', () => {
|
|
19
|
+
it('should get public key from private key', () => {
|
|
20
|
+
const publicKeyFromPrivateKey = publicKeyHexFromPEM(PEM_PRIV_KEY)
|
|
21
|
+
expect(publicKeyFromPrivateKey).toEqual(
|
|
22
|
+
'30820122300d06092a864886f70d01010105000382010f003082010a0282010100d5eb1f8708914a91581b7945b2f620963859b5279bcd9db3830cc6ac1cf8e9f26ecf8f6cc1a9d914b099fad9c4c4360008d1be9507f893b6ac32a5d6144314da8c4867526ffd15e41ff2f8fc0b7e0e23cf343de8607af88242b0a55ab2f38c371c12fa105522adcfc0356337374aabb0f2e41f14a56a3c20cacba9d58e14de0c78fdb710494dfa261fe5981e90f7b2e9915eedc6079c59406c02e87db772b689a55d51c370ffcfb9c596a960f40419c129e3bc8f8b1389d92997a68476893a6f64ae19372177271a8a420da9189a956d5a2fb614b07714243aa176d686d077a22225cbc39a71d2c4ba3a0e21c1198118c493bcdcf4a44d8dd7ca1ef264c024530203010001'
|
|
23
|
+
)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('cert chains should be converted to x5c and vice versa', async () => {
|
|
27
|
+
const x5c = pemCertChainTox5c(PEM_FULL_CHAIN)
|
|
28
|
+
expect(x5c).toHaveLength(3)
|
|
29
|
+
const chain = x5cToPemCertChain(x5c)
|
|
30
|
+
expect(chain).toHaveLength(PEM_FULL_CHAIN.length)
|
|
31
|
+
expect(chain).toContain(PEM_CERT)
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
describe('x509 keys', () => {
|
|
35
|
+
it('should sign and verify', async () => {
|
|
36
|
+
const jsEncryptGenerated = new JSEncrypt()
|
|
37
|
+
const keyPair = jsEncryptGenerated.getKey()
|
|
38
|
+
const privPEM = keyPair.getPrivateKey()
|
|
39
|
+
const pubPEM = keyPair.getPublicKey()
|
|
40
|
+
|
|
41
|
+
const jsEncryptImported = new JSEncrypt()
|
|
42
|
+
jsEncryptImported.setKey(privPEM)
|
|
43
|
+
|
|
44
|
+
const jsEncryptPubOnly = new JSEncrypt()
|
|
45
|
+
jsEncryptPubOnly.setKey(pubPEM)
|
|
46
|
+
|
|
47
|
+
const sha256 = digestMethodParams('SHA-256')
|
|
48
|
+
const signed = jsEncryptImported.sign('test', sha256.digestMethod, sha256.hashAlgorithm)
|
|
49
|
+
expect(signed).toHaveLength(172)
|
|
50
|
+
|
|
51
|
+
expect(jsEncryptPubOnly.verify('test', signed as string, sha256.digestMethod)).toBeTruthy()
|
|
52
|
+
})
|
|
53
|
+
it('should export private key to private Key Object', async () => {
|
|
54
|
+
const keyObject = toKeyObject(PEM_PRIV_KEY, 'private')
|
|
55
|
+
expect(keyObject.keyType).toEqual('private')
|
|
56
|
+
expect(keyObject.keyHex).toEqual(
|
|
57
|
+
'308204bf020100300d06092a864886f70d0101010500048204a9308204a50201000282010100d5eb1f8708914a91581b7945b2f620963859b5279bcd9db3830cc6ac1cf8e9f26ecf8f6cc1a9d914b099fad9c4c4360008d1be9507f893b6ac32a5d6144314da8c4867526ffd15e41ff2f8fc0b7e0e23cf343de8607af88242b0a55ab2f38c371c12fa105522adcfc0356337374aabb0f2e41f14a56a3c20cacba9d58e14de0c78fdb710494dfa261fe5981e90f7b2e9915eedc6079c59406c02e87db772b689a55d51c370ffcfb9c596a960f40419c129e3bc8f8b1389d92997a68476893a6f64ae19372177271a8a420da9189a956d5a2fb614b07714243aa176d686d077a22225cbc39a71d2c4ba3a0e21c1198118c493bcdcf4a44d8dd7ca1ef264c02453020301000102820101009576685ad2b3a124182969fc36e41d34983ea581fd2c16c97c010b36ea2f485628f240c5be324c0856b3df3f1469fb48dee09d8647417903a320e819c1a275099606689a82c093f106199fb98ad6124f16d0eb885710d45d3ef769310be37ace6e811bd31988d764566976def774e6ad05a839c715243acab6a6c20d01eeb68d3d0eec83b098d3ceda31eca32a42121b59229f424975f47061006d766a6cbe18d5857b5e06a8b25e1ca0fd792bb7afb92b83c7d4180482f83bbce0cf55fb3b640a72cd93de0f419fe7e0a1c60d495641afc5cd692c0bde4c71fde0d3501e5b6cf8aa285514613c1e7399d20918e383a7daa370af898dde24242f3486006e503102818100f498cfafc7b004682d6902a67b9f7e316051ab375c35193e3f9307d53041f7d8e1c238503561af52cd23e1ff7ed6c50b32e9ff38bfafd0eb2bd8bd5f4c30c49d2101938c048aff105fe3e66c60acdea069e5cef9575277ab737636c77ae0d08bbf56083fe53d967b0c6a9532c3a44df0742ad58f030e8d86e55444b16621498d02818100dfe42c7f598d07663a7db562d840d2cb9b5d902c8f2855184b2e7c5556a803cb5df12b63524d058476306a8a3adc614ebafb494c5fcc465f0831b817405061297b15a95565d4a4bd820fa66959590c32ef9929629c5f16a38e8591d55e056fcf597adb6f997bbfdcaef5ea9692abd73737a5911cb5d59ed44b0e0d088e6c7d5f028180449dcdbd812656c626df0b984a9bde99d96c6fbcb3084e5191221d13685b493d356ff7be408b6bd4ada9c04f9d74808878bafe171c672513a4144463c48af5cd22a23f930aff37388fbdee393f119fce9e86927e8e499b3aa4c467efa4000760fcc714bf5ffedc051ee193834f30fb9055f6623ca15de6c40df78ae1bd45df4d02818100b9c40faba6b8de3fd31e44a6fbf9652dacfe87c6810d9cf56843ecc3bdfff00e082737b1d432b5f63f3e52d7d898cc604fc27a01d5a69f68f05a987d2a4ec71f6cd1ff4b2d0faf94d1da7c6002d360ccce824d95555b8c642eb7e2d59f8a714820dd503f1ba153031f6449bd9f7ad73a2880c69384c7f75dfbdc6fb1fec2438f02818100df333c3157e5e861fc1bb4db910c628b5dcbff481f0ed036c4a7f2a517ff390cb0c5cbb44fc02351738e0df74d3b5345c48e728cbacd1752ac04fb482829c3037f0de6f8f8de9a9395aa740b07a2608877eb570406aba25563dd1f187f6b9c0b3e9aec71487c56999a91436a0e76da27caf444578e2782bc1ee2718af0ee4de0'
|
|
58
|
+
)
|
|
59
|
+
expect(keyObject.pem).toEqual(PEM_PRIV_KEY + '\n')
|
|
60
|
+
expect(keyObject.jwk).toEqual({
|
|
61
|
+
kty: 'RSA',
|
|
62
|
+
n: '1esfhwiRSpFYG3lFsvYgljhZtSebzZ2zgwzGrBz46fJuz49swanZFLCZ-tnExDYACNG-lQf4k7asMqXWFEMU2oxIZ1Jv_RXkH_L4_At-DiPPND3oYHr4gkKwpVqy84w3HBL6EFUirc_ANWM3N0qrsPLkHxSlajwgysup1Y4U3gx4_bcQSU36Jh_lmB6Q97LpkV7txgecWUBsAuh9t3K2iaVdUcNw_8-5xZapYPQEGcEp47yPixOJ2SmXpoR2iTpvZK4ZNyF3JxqKQg2pGJqVbVovthSwdxQkOqF21obQd6IiJcvDmnHSxLo6DiHBGYEYxJO83PSkTY3Xyh7yZMAkUw',
|
|
63
|
+
e: 'AQAB',
|
|
64
|
+
d: 'lXZoWtKzoSQYKWn8NuQdNJg-pYH9LBbJfAELNuovSFYo8kDFvjJMCFaz3z8UaftI3uCdhkdBeQOjIOgZwaJ1CZYGaJqCwJPxBhmfuYrWEk8W0OuIVxDUXT73aTEL43rOboEb0xmI12RWaXbe93TmrQWoOccVJDrKtqbCDQHuto09DuyDsJjTztox7KMqQhIbWSKfQkl19HBhAG12amy-GNWFe14GqLJeHKD9eSu3r7krg8fUGASC-Du84M9V-ztkCnLNk94PQZ_n4KHGDUlWQa_FzWksC95Mcf3g01AeW2z4qihVFGE8HnOZ0gkY44On2qNwr4mN3iQkLzSGAG5QMQ',
|
|
65
|
+
p: '9JjPr8ewBGgtaQKme59-MWBRqzdcNRk-P5MH1TBB99jhwjhQNWGvUs0j4f9-1sULMun_OL-v0Osr2L1fTDDEnSEBk4wEiv8QX-PmbGCs3qBp5c75V1J3q3N2Nsd64NCLv1YIP-U9lnsMapUyw6RN8HQq1Y8DDo2G5VREsWYhSY0',
|
|
66
|
+
q: '3-Qsf1mNB2Y6fbVi2EDSy5tdkCyPKFUYSy58VVaoA8td8StjUk0FhHYwaoo63GFOuvtJTF_MRl8IMbgXQFBhKXsVqVVl1KS9gg-maVlZDDLvmSlinF8Wo46FkdVeBW_PWXrbb5l7v9yu9eqWkqvXNzelkRy11Z7USw4NCI5sfV8',
|
|
67
|
+
dp: 'RJ3NvYEmVsYm3wuYSpvemdlsb7yzCE5RkSIdE2hbST01b_e-QItr1K2pwE-ddICIeLr-FxxnJROkFERjxIr1zSKiP5MK_zc4j73uOT8Rn86ehpJ-jkmbOqTEZ--kAAdg_McUv1_-3AUe4ZODTzD7kFX2YjyhXebEDfeK4b1F300',
|
|
68
|
+
dq: 'ucQPq6a43j_THkSm-_llLaz-h8aBDZz1aEPsw73_8A4IJzex1DK19j8-UtfYmMxgT8J6AdWmn2jwWph9Kk7HH2zR_0stD6-U0dp8YALTYMzOgk2VVVuMZC634tWfinFIIN1QPxuhUwMfZEm9n3rXOiiAxpOEx_dd-9xvsf7CQ48',
|
|
69
|
+
qi: '3zM8MVfl6GH8G7TbkQxii13L_0gfDtA2xKfypRf_OQywxcu0T8AjUXOODfdNO1NFxI5yjLrNF1KsBPtIKCnDA38N5vj43pqTlap0CweiYIh361cEBquiVWPdHxh_a5wLPprscUh8VpmakUNqDnbaJ8r0RFeOJ4K8HuJxivDuTeA',
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('should export private key to public Key Object', async () => {
|
|
74
|
+
const keyObject = toKeyObject(PEM_PRIV_KEY, 'public')
|
|
75
|
+
expect(keyObject.keyType).toEqual('public')
|
|
76
|
+
expect(keyObject.keyHex).toEqual(
|
|
77
|
+
'30820122300d06092a864886f70d01010105000382010f003082010a0282010100d5eb1f8708914a91581b7945b2f620963859b5279bcd9db3830cc6ac1cf8e9f26ecf8f6cc1a9d914b099fad9c4c4360008d1be9507f893b6ac32a5d6144314da8c4867526ffd15e41ff2f8fc0b7e0e23cf343de8607af88242b0a55ab2f38c371c12fa105522adcfc0356337374aabb0f2e41f14a56a3c20cacba9d58e14de0c78fdb710494dfa261fe5981e90f7b2e9915eedc6079c59406c02e87db772b689a55d51c370ffcfb9c596a960f40419c129e3bc8f8b1389d92997a68476893a6f64ae19372177271a8a420da9189a956d5a2fb614b07714243aa176d686d077a22225cbc39a71d2c4ba3a0e21c1198118c493bcdcf4a44d8dd7ca1ef264c024530203010001'
|
|
78
|
+
)
|
|
79
|
+
expect(keyObject.pem).toEqual(
|
|
80
|
+
'-----BEGIN PUBLIC KEY-----\n' +
|
|
81
|
+
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1esfhwiRSpFYG3lFsvYg\n' +
|
|
82
|
+
'ljhZtSebzZ2zgwzGrBz46fJuz49swanZFLCZ+tnExDYACNG+lQf4k7asMqXWFEMU\n' +
|
|
83
|
+
'2oxIZ1Jv/RXkH/L4/At+DiPPND3oYHr4gkKwpVqy84w3HBL6EFUirc/ANWM3N0qr\n' +
|
|
84
|
+
'sPLkHxSlajwgysup1Y4U3gx4/bcQSU36Jh/lmB6Q97LpkV7txgecWUBsAuh9t3K2\n' +
|
|
85
|
+
'iaVdUcNw/8+5xZapYPQEGcEp47yPixOJ2SmXpoR2iTpvZK4ZNyF3JxqKQg2pGJqV\n' +
|
|
86
|
+
'bVovthSwdxQkOqF21obQd6IiJcvDmnHSxLo6DiHBGYEYxJO83PSkTY3Xyh7yZMAk\n' +
|
|
87
|
+
'UwIDAQAB\n' +
|
|
88
|
+
'-----END PUBLIC KEY-----\n'
|
|
89
|
+
)
|
|
90
|
+
expect(keyObject.jwk).toEqual({
|
|
91
|
+
e: 'AQAB',
|
|
92
|
+
kty: 'RSA',
|
|
93
|
+
n: '1esfhwiRSpFYG3lFsvYgljhZtSebzZ2zgwzGrBz46fJuz49swanZFLCZ-tnExDYACNG-lQf4k7asMqXWFEMU2oxIZ1Jv_RXkH_L4_At-DiPPND3oYHr4gkKwpVqy84w3HBL6EFUirc_ANWM3N0qrsPLkHxSlajwgysup1Y4U3gx4_bcQSU36Jh_lmB6Q97LpkV7txgecWUBsAuh9t3K2iaVdUcNw_8-5xZapYPQEGcEp47yPixOJ2SmXpoR2iTpvZK4ZNyF3JxqKQg2pGJqVbVovthSwdxQkOqF21obQd6IiJcvDmnHSxLo6DiHBGYEYxJO83PSkTY3Xyh7yZMAkUw',
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
describe('@veramo/kms-local x509 import', () => {
|
|
99
|
+
const x509: X509Opts = {
|
|
100
|
+
cn: 'f825-87-213-241-251.eu.ngrok.io',
|
|
101
|
+
certificatePEM: PEM_CERT,
|
|
102
|
+
certificateChainPEM: PEM_CHAIN,
|
|
103
|
+
privateKeyPEM: PEM_PRIV_KEY,
|
|
104
|
+
certificateChainURL: 'https://example.com/.wellknown/fullchain.pem',
|
|
105
|
+
}
|
|
106
|
+
const privateKeyHex = privateKeyHexFromPEM(PEM_PRIV_KEY)
|
|
107
|
+
const meta = {
|
|
108
|
+
x509,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
it('should import a cert with chain', async () => {
|
|
112
|
+
const kms = new SphereonKeyManagementSystem(new MemoryPrivateKeyStore())
|
|
113
|
+
|
|
114
|
+
// @ts-ignore
|
|
115
|
+
const key = await kms.importKey({ kid: 'test', privateKeyHex, type: 'RSA', meta })
|
|
116
|
+
expect(key.type).toEqual('RSA')
|
|
117
|
+
expect(key.publicKeyHex).toEqual(
|
|
118
|
+
'30820122300d06092a864886f70d01010105000382010f003082010a0282010100d5eb1f8708914a91581b7945b2f620963859b5279bcd9db3830cc6ac1cf8e9f26ecf8f6cc1a9d914b099fad9c4c4360008d1be9507f893b6ac32a5d6144314da8c4867526ffd15e41ff2f8fc0b7e0e23cf343de8607af88242b0a55ab2f38c371c12fa105522adcfc0356337374aabb0f2e41f14a56a3c20cacba9d58e14de0c78fdb710494dfa261fe5981e90f7b2e9915eedc6079c59406c02e87db772b689a55d51c370ffcfb9c596a960f40419c129e3bc8f8b1389d92997a68476893a6f64ae19372177271a8a420da9189a956d5a2fb614b07714243aa176d686d077a22225cbc39a71d2c4ba3a0e21c1198118c493bcdcf4a44d8dd7ca1ef264c024530203010001'
|
|
119
|
+
)
|
|
120
|
+
expect(key.kid).toEqual('test')
|
|
121
|
+
expect(key.meta?.algorithms).toEqual(['RS256', 'RS512', 'PS256', 'PS512'])
|
|
122
|
+
|
|
123
|
+
expect(key.meta?.publicKeyPEM).toBeDefined()
|
|
124
|
+
await expect(key.meta?.publicKeyJwk).toMatchObject({
|
|
125
|
+
kty: 'RSA',
|
|
126
|
+
n: '1esfhwiRSpFYG3lFsvYgljhZtSebzZ2zgwzGrBz46fJuz49swanZFLCZ-tnExDYACNG-lQf4k7asMqXWFEMU2oxIZ1Jv_RXkH_L4_At-DiPPND3oYHr4gkKwpVqy84w3HBL6EFUirc_ANWM3N0qrsPLkHxSlajwgysup1Y4U3gx4_bcQSU36Jh_lmB6Q97LpkV7txgecWUBsAuh9t3K2iaVdUcNw_8-5xZapYPQEGcEp47yPixOJ2SmXpoR2iTpvZK4ZNyF3JxqKQg2pGJqVbVovthSwdxQkOqF21obQd6IiJcvDmnHSxLo6DiHBGYEYxJO83PSkTY3Xyh7yZMAkUw',
|
|
127
|
+
e: 'AQAB',
|
|
128
|
+
x5u: 'https://example.com/.wellknown/fullchain.pem',
|
|
129
|
+
})
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
it('should sign input data', async () => {
|
|
133
|
+
const kms = new SphereonKeyManagementSystem(new MemoryPrivateKeyStore())
|
|
134
|
+
const data = u8a.fromString('test', 'utf-8')
|
|
135
|
+
|
|
136
|
+
// @ts-ignore
|
|
137
|
+
const key = await kms.importKey({ kid: 'test', privateKeyHex, type: 'RSA', meta })
|
|
138
|
+
const signature = await kms.sign({ keyRef: key, data, algorithm: 'RS256' })
|
|
139
|
+
expect(signature).toEqual(
|
|
140
|
+
'PAgf2uRWJa-pmlUL80NVnxkExJkcpfLPB8udX1WoFGtAnIuFCfq8r1C43NL0xr9Qtn8TBK5pVHmAPPd7XlTkXU_LQ_JoBYxjzjtaRzGOo4-S-TAtKaW-evGI5rpXFWCeta0gwzTCVfDjbouRUg3_krK0B1cLLK1Kiih83n-6hadTxPLiQqNpbWxbnoHbZXw-V-5maCE1erY9cvO9LZeO2S_PXiqb19gk4mOEG3ZRQm12eHAlOVTnqRYiLmwWfSnT231jkJnF99RuLUjxlQNO5K6B-vYIhfVoqDliqaW6IEOamJJHUWG6RlqZfU7TzanZzR0YmDf5HIJEiDG4D_lF6g'
|
|
141
|
+
)
|
|
142
|
+
})
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
describe('RSA Signer', () => {
|
|
146
|
+
it('should sign and verify', async () => {
|
|
147
|
+
const signer = new RSASigner(PEMToJwk(PEM_PRIV_KEY, 'private'), {
|
|
148
|
+
hashAlgorithm: 'SHA-256',
|
|
149
|
+
scheme: 'RSASSA-PKCS1-V1_5',
|
|
150
|
+
})
|
|
151
|
+
const signature = await signer.sign('test123')
|
|
152
|
+
expect(signature).toBeDefined()
|
|
153
|
+
const result = await signer.verify('test123', signature)
|
|
154
|
+
expect(result).toBeTruthy()
|
|
155
|
+
})
|
|
156
|
+
})
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { TKeyType } from '@veramo/core'
|
|
2
|
+
export { SphereonKeyManagementSystem } from './SphereonKeyManagementSystem'
|
|
3
|
+
export type BlsManagedKeyInfoArgs = { alias?: string; type: TKeyType; privateKeyHex: string; publicKeyHex?: string }
|
|
4
|
+
export enum KeyType {
|
|
5
|
+
Bls12381G2 = 'Bls12381G2',
|
|
6
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { hash as sha256 } from '@stablelib/sha256'
|
|
2
|
+
import { hash as sha512 } from '@stablelib/sha512'
|
|
3
|
+
import * as u8a from 'uint8arrays'
|
|
4
|
+
|
|
5
|
+
export type HashAlgorithm = 'SHA-256' | 'SHA-512'
|
|
6
|
+
export type TDigestMethod = (input: string) => string
|
|
7
|
+
|
|
8
|
+
export const digestMethodParams = (hashAlgorithm: HashAlgorithm): { hashAlgorithm: HashAlgorithm; digestMethod: TDigestMethod } => {
|
|
9
|
+
if (hashAlgorithm === 'SHA-256') {
|
|
10
|
+
return { hashAlgorithm: 'SHA-256', digestMethod: sha256DigestMethod }
|
|
11
|
+
} else {
|
|
12
|
+
return { hashAlgorithm: 'SHA-512', digestMethod: sha512DigestMethod }
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const sha256DigestMethod = (input: string): string => {
|
|
17
|
+
return u8a.toString(sha256(u8a.fromString(input, 'utf-8')), 'base16')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const sha512DigestMethod = (input: string): string => {
|
|
21
|
+
return u8a.toString(sha512(u8a.fromString(input, 'utf-8')), 'base16')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/*
|
|
25
|
+
// PKCS#1 (PSS) mask generation function
|
|
26
|
+
function pss_mgf1_str(seed, len, hash) {
|
|
27
|
+
var mask = '', i = 0;
|
|
28
|
+
|
|
29
|
+
while (mask.length < len) {
|
|
30
|
+
mask += hextorstr(hash(rstrtohex(seed + String.fromCharCode.apply(String, [
|
|
31
|
+
(i & 0xff000000) >> 24,
|
|
32
|
+
(i & 0x00ff0000) >> 16,
|
|
33
|
+
(i & 0x0000ff00) >> 8,
|
|
34
|
+
i & 0x000000ff]))));
|
|
35
|
+
i += 1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return mask;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/*
|
|
44
|
+
|
|
45
|
+
/!**
|
|
46
|
+
* Generate mask of specified length.
|
|
47
|
+
*
|
|
48
|
+
* @param {String} seed The seed for mask generation.
|
|
49
|
+
* @param maskLen Number of bytes to generate.
|
|
50
|
+
* @return {String} The generated mask.
|
|
51
|
+
*!/
|
|
52
|
+
export const mgf1 = (dm: TDigestMethod, seed: string, maskLen: number) => {
|
|
53
|
+
/!* 2. Let T be the empty octet string. *!/
|
|
54
|
+
var t = new forge.util.ByteBuffer();
|
|
55
|
+
|
|
56
|
+
/!* 3. For counter from 0 to ceil(maskLen / hLen), do the following: *!/
|
|
57
|
+
var len = Math.ceil(maskLen / md.digestLength);
|
|
58
|
+
for(var i = 0; i < len; i++) {
|
|
59
|
+
/!* a. Convert counter to an octet string C of length 4 octets *!/
|
|
60
|
+
var c = new forge.util.ByteBuffer();
|
|
61
|
+
c.putInt32(i);
|
|
62
|
+
|
|
63
|
+
/!* b. Concatenate the hash of the seed mgfSeed and C to the octet
|
|
64
|
+
* string T: *!/
|
|
65
|
+
md.start();
|
|
66
|
+
md.update(seed + c.getBytes());
|
|
67
|
+
t.putBuffer(md.digest());
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/!* Output the leading maskLen octets of T as the octet string mask. *!/
|
|
71
|
+
t.truncate(t.length() - maskLen);
|
|
72
|
+
return t.getBytes();
|
|
73
|
+
}
|
|
74
|
+
*/
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { base64ToPEM, JWK } from '@sphereon/ssi-sdk-did-utils'
|
|
2
|
+
import crypto from '@sphereon/isomorphic-webcrypto'
|
|
3
|
+
import { HashAlgorithm } from './digest-methods'
|
|
4
|
+
import * as u8a from 'uint8arrays'
|
|
5
|
+
|
|
6
|
+
export type RSASignatureSchemes = 'RSASSA-PKCS1-V1_5' | 'RSA-PSS'
|
|
7
|
+
|
|
8
|
+
export type RSAEncryptionSchemes = 'RSAES-PKCS-v1_5 ' | 'RSAES-OAEP'
|
|
9
|
+
|
|
10
|
+
const usage = (jwk: JWK): KeyUsage[] => {
|
|
11
|
+
// "decrypt" | "deriveBits" | "deriveKey" | "encrypt" | "sign" | "unwrapKey" | "verify" | "wrapKey";
|
|
12
|
+
return jwk.d ? ['sign', 'decrypt', 'verify', 'encrypt'] : ['verify', 'encrypt']
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const signAlgorithmToSchemeAndHashAlg = (signingAlg: string) => {
|
|
16
|
+
const alg = signingAlg.toUpperCase()
|
|
17
|
+
let scheme: RSAEncryptionSchemes | RSASignatureSchemes
|
|
18
|
+
if (alg.startsWith('RS')) {
|
|
19
|
+
scheme = 'RSASSA-PKCS1-V1_5'
|
|
20
|
+
} else if (alg.startsWith('PS')) {
|
|
21
|
+
scheme = 'RSA-PSS'
|
|
22
|
+
} else {
|
|
23
|
+
throw Error(`Invalid signing algorithm supplied ${signingAlg}`)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const hashAlgorithm = `SHA-${alg.substring(2)}` as HashAlgorithm
|
|
27
|
+
return { scheme, hashAlgorithm }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const importRSAKey = async (
|
|
31
|
+
jwk: JWK,
|
|
32
|
+
scheme: RSAEncryptionSchemes | RSASignatureSchemes,
|
|
33
|
+
hashAlgorithm?: HashAlgorithm
|
|
34
|
+
): Promise<CryptoKey> => {
|
|
35
|
+
const hashName = hashAlgorithm ? hashAlgorithm : jwk.alg ? `SHA-${jwk.alg.substring(2)}` : 'SHA-256'
|
|
36
|
+
|
|
37
|
+
const importParams: RsaHashedImportParams = { name: scheme, hash: hashName }
|
|
38
|
+
return await crypto.subtle.importKey('jwk', jwk as JsonWebKey, importParams, false, usage(jwk))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const generateRSAKeyAsPEM = async (
|
|
42
|
+
scheme: RSAEncryptionSchemes | RSASignatureSchemes,
|
|
43
|
+
hashAlgorithm?: HashAlgorithm,
|
|
44
|
+
modulusLength?: number
|
|
45
|
+
): Promise<string> => {
|
|
46
|
+
const hashName = hashAlgorithm ? hashAlgorithm : 'SHA-256'
|
|
47
|
+
|
|
48
|
+
const params: RsaHashedKeyGenParams = {
|
|
49
|
+
name: scheme,
|
|
50
|
+
hash: hashName,
|
|
51
|
+
modulusLength: modulusLength ? modulusLength : 2048,
|
|
52
|
+
publicExponent: new Uint8Array([1, 0, 1]),
|
|
53
|
+
}
|
|
54
|
+
const keyUsage: KeyUsage[] = scheme === 'RSA-PSS' || scheme === 'RSASSA-PKCS1-V1_5' ? ['sign', 'verify'] : ['encrypt', 'decrypt']
|
|
55
|
+
|
|
56
|
+
const keypair = await crypto.subtle.generateKey(params, true, keyUsage)
|
|
57
|
+
const pkcs8 = await crypto.subtle.exportKey('pkcs8', keypair.privateKey)
|
|
58
|
+
|
|
59
|
+
const uint8Array = new Uint8Array(pkcs8)
|
|
60
|
+
return base64ToPEM(u8a.toString(uint8Array, 'base64pad'), 'RSA PRIVATE KEY')
|
|
61
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { JWK, PEMToJwk } from '@sphereon/ssi-sdk-did-utils'
|
|
2
|
+
import * as u8a from 'uint8arrays'
|
|
3
|
+
import { HashAlgorithm } from './digest-methods'
|
|
4
|
+
import crypto from '@sphereon/isomorphic-webcrypto'
|
|
5
|
+
import { importRSAKey, RSAEncryptionSchemes, RSASignatureSchemes } from './rsa-key'
|
|
6
|
+
|
|
7
|
+
export class RSASigner {
|
|
8
|
+
private readonly hashAlgorithm: HashAlgorithm
|
|
9
|
+
private readonly jwk: JWK
|
|
10
|
+
|
|
11
|
+
private key: CryptoKey | undefined
|
|
12
|
+
private readonly scheme: RSAEncryptionSchemes | RSASignatureSchemes
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param key Either in PEM or JWK format (no raw hex keys here!)
|
|
17
|
+
* @param hashAlgorithm
|
|
18
|
+
*/
|
|
19
|
+
constructor(key: string | JWK, opts?: { hashAlgorithm?: HashAlgorithm; scheme?: RSAEncryptionSchemes | RSASignatureSchemes }) {
|
|
20
|
+
if (typeof key === 'string') {
|
|
21
|
+
this.jwk = PEMToJwk(key)
|
|
22
|
+
} else {
|
|
23
|
+
this.jwk = key
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
this.hashAlgorithm = opts?.hashAlgorithm ?? 'SHA-256'
|
|
27
|
+
this.scheme = opts?.scheme ?? 'RSA-PSS'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
private getImportParams(): AlgorithmIdentifier {
|
|
31
|
+
// console.log({ name: this.scheme /*, hash: this.hashAlgorithm*/ })
|
|
32
|
+
return { name: this.scheme /*, hash: this.hashAlgorithm*/ }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private async getKey(): Promise<CryptoKey> {
|
|
36
|
+
if (!this.key) {
|
|
37
|
+
this.key = await importRSAKey(this.jwk, this.scheme, this.hashAlgorithm)
|
|
38
|
+
}
|
|
39
|
+
return this.key
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private bufferToString(buf: ArrayBuffer) {
|
|
43
|
+
const uint8Array = new Uint8Array(buf)
|
|
44
|
+
return u8a.toString(uint8Array, 'base64url') // Needs to be base64url for JsonWebSignature2020. Don't change!
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
public async sign(data: string | Uint8Array): Promise<string> {
|
|
48
|
+
const input = typeof data === 'string' ? u8a.fromString(data, 'utf-8') : data
|
|
49
|
+
const key = await this.getKey()
|
|
50
|
+
const signature = this.bufferToString(await crypto.subtle.sign(this.getImportParams(), key, input))
|
|
51
|
+
if (!signature) {
|
|
52
|
+
throw Error('Could not sign input data')
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// base64url signature
|
|
56
|
+
return signature
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public async verify(data: string | Uint8Array, signature: string | Uint8Array): Promise<boolean> {
|
|
60
|
+
const sig = typeof signature === 'string' ? signature : u8a.toString(signature, 'base64url')
|
|
61
|
+
const jws = sig.includes('.') ? sig.split('.')[2] : sig
|
|
62
|
+
|
|
63
|
+
const input = typeof data == 'string' ? u8a.fromString(data, 'utf-8') : data
|
|
64
|
+
const verificationResult = await crypto.subtle.verify(this.getImportParams(), await this.getKey(), u8a.fromString(jws, 'base64url'), input)
|
|
65
|
+
return verificationResult
|
|
66
|
+
}
|
|
67
|
+
}
|