Merge branch 'dev' into feat/rsapss-zkemail-tests

This commit is contained in:
seshanthS
2025-01-10 23:54:02 +05:30
175 changed files with 792316 additions and 10092 deletions

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -460,9 +460,9 @@ gWumsjuDKbjOOuFdGUDURNtlREjxrnq/NGXVVnCyqsdo8JpZysABSf/eNs0D9o0w
w/h8qiuaZaVrlZ7Jjeo7ajGtQ06VNH89Uj6z/+QOlcntXy1Z8kHLj5uK5jgqhStZ
HSmnugxx7VOXBDVklCt1ONz8PwAa+0X0nGJNemoC3cunZqRlncBucjy7M7lrGeS+
iySrEW15LP1BIewmCV9GYliauC5xffKa+IfCJnm3zw==
-----END CERTIFICATE-----`
-----END CERTIFICATE-----`;
export const mock_dsc_key_sha256_rsapss_65537_3072=`-----BEGIN PRIVATE KEY-----
export const mock_dsc_key_sha256_rsapss_65537_3072 = `-----BEGIN PRIVATE KEY-----
MIIG/QIBADANBgkqhkiG9w0BAQEFAASCBucwggbjAgEAAoIBgQDjX/MuuvRWk0lP
5S2LjsvKcF6CFTfTgYtlTF6C/l/05cYluvmWGi5YjuYTYewTl2YOyKUOJqpLKIXx
PEn/U8aVP692nn83UAdaxoJI0YIHoURDe/cmXN0YdTysOsEpxrjyMuKPker//FGW
@@ -502,9 +502,9 @@ mb5trSbPl10irtAMkZPHduBf7bdws6+6285JP9utc6SWCRRHj9yl4O0MaURnGXdx
sNmBlVp81RaPf5NAbe38eRBtcAKG5V9nis45QefWOCJ4Dnm69HZ1H6ozVrzt4HQm
iI26TdrqkM7g7vzOS0gOEMI=
-----END PRIVATE KEY-----
`
`;
export const mock_dsc_sha256_rsapss_65537_3072=`-----BEGIN CERTIFICATE-----
export const mock_dsc_sha256_rsapss_65537_3072 = `-----BEGIN CERTIFICATE-----
MIIEwjCCAvagAwIBAgIUZflxS6VTZ+x2jttEfGIaE/bBrSAwQQYJKoZIhvcNAQEK
MDSgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEF
AKIDAgEgMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
@@ -531,7 +531,7 @@ NuZ46gmB8zMj2UewCVzaJ7RFXfvejbGccwtpLRy7BBBVO5ZRWh79BsWEq0HSLtBa
KpveLtZpGLwRHMAVhWftT70J3lzrE3OcGWcGV8Ubdx0Cv1/c6ikShLnEEwwV4BoQ
sDghA5MyF+3oxZc3/gyhaM/zvGgyeF8m3xhmlySPXstIOBONiX7jw7hq8uIu1ctN
0Kc3XOb+BAqHQvSCXISshZ1xreF/xg==
-----END CERTIFICATE-----`
-----END CERTIFICATE-----`;
export const mock_csca_key_rsapss_65537_4096 = `
-----BEGIN PRIVATE KEY-----
@@ -618,7 +618,7 @@ ONLHppLKnaF2G0+8K2m8SaYR0evVUHacQjKA/yNtlP+zpCm7Zw6E4bLHL+/p2CUO
l1g0QvM9uulWFQeQA3Ds5GGsc7WSztFQLe+Mw1wmfnaGvbCCZNGdfV91Gxbu+0Um
JOOn3mnc4Pgz8INvMIe7BkwquWZT5Dh/D3zHY2O2rFojioAVl1ibCxZkbX0q/BXh
qztITe2ZDOHrXoVJ1U//rqM0aSO5JcKRXk5E9VcWW5vQnVXX+3wr/P7l9ClN3w==
-----END CERTIFICATE-----`
-----END CERTIFICATE-----`;
export const mock_dsc_key_rsapss_65537_4096 = `-----BEGIN PRIVATE KEY-----
MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQDUGaAQSOhZZQrL
@@ -672,7 +672,7 @@ odQlepVKCWIav4YuqA1i9TG2qCVjB379ERBOBoNJ0Q3C5bv6au2+TLQvH/R/e1ed
3XkgZ8ec+IU8tzJX7Zubg/cCSzESJsxdNzYUsBQwSEiVmrsKoJ5lK92CZxHGueIM
VIC18b9mdJu8A6U7N3q4AaFS0oBQ
-----END PRIVATE KEY-----
`
`;
export const mock_dsc_sha256_rsapss_65537_4096 = `-----BEGIN CERTIFICATE-----
MIIFwjCCA3agAwIBAgIUegbEJKS0EoxaWTW81zA0wSo1q/4wQQYJKoZIhvcNAQEK
@@ -706,7 +706,7 @@ LY4bleprE+8yX+MPkjjPD4o/NwNPSkjXQJVOxOglPOG7Eh4lPglR/O8eIZ+NZnWD
vsEOVqs7EZdPW8h08ic1EGjJCQB/tfFJ/vzP0CfOLhhnokAA81+4rMiGHPv7+fi3
nb03Vb90cletIyOwobD8mufnYD0ua3c4id0WopafR4MF91zr7CXEuvQVcOYfZKY/
0LemzFv4pbb+9t44QS3w0OmvENW8ZLRzjzXoSniHqqLlAJ7OmTY=
-----END CERTIFICATE-----`
-----END CERTIFICATE-----`;
export const mock_csca_sha384_rsapss_65537_3072 = `
-----BEGIN CERTIFICATE-----
@@ -776,7 +776,7 @@ fQyrSx5WCO04wbRsEQbHwtdq7QGcegyaWich/u3AIrypMyd4wAaBXxS7jDThulM7
3G8+pRbRRBBdEiTK45RM7nahf0zA2qm2VIG16NtZTOUJZqK2AxQjnYxQWhC0X/FA
T5gGnl33WcF2FjfqwPwEUBkd+W7r8WKDGnTkBctyc1IyxIiOPIi3nIXPhQrJxA/R
AHThNL5pYxeq+tNRsvPYY90=
-----END PRIVATE KEY-----`
-----END PRIVATE KEY-----`;
export const mock_dsc_sha384_rsapss_65537_3072 = `-----BEGIN CERTIFICATE-----
MIIEwjCCAvagAwIBAgIUKp13XbOipd9/h7Vmx21KMC4I40swQQYJKoZIhvcNAQEK
@@ -806,7 +806,7 @@ niOQ/EOeQNP7BK//Gc9YJR8CM1uypZmw4MAoYRsllhE98wo5t7K+Yh3XbEIxZTSU
fs8LHRtGciln2kBjHJSRifhPFSXILGgEPRPvOMHgDHLzr7QFajskU3fv/MV2zqfS
10b7qUNrwvURph+aXyMiamRoVvp6KA==
-----END CERTIFICATE-----
`
`;
export const mock_csca_key_sha256_rsapss_3_4096 = `-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDydOy1SpmPOD/h
@@ -842,7 +842,7 @@ y00BVp5UAQry8PX44G2xkXpAEW4pBs5XlMRTAIZiv3DtCSvI7XEfJuPUXhBCA0E4
A/1QCkPCcxlmlW0IEvGyp/sw72O3TOFDb5Gwf7WgYuu5en4ZmONNX7fKvqtq8Xsq
Bqf6X9iYShjOpdHuX9tGURWgc3HzY1Ma6Q+8ls2mTUsA5ts8IXDXQDuG5cLoPMIF
IaPHCe6w0yEsmBjqhqZfkPxbJwW6OimbDaP6Eh0FYBCv6rhakZIswUceWhdUQHaV
OQk/OfA1zDMCggEBAKkhi/876Pjw4I0zbPZ2o+wxGhaIr93PIRwBPSByMPvqZFYy
OQk/OfA1zDMCggEBAKkhi/876Pjw4I0zbPZ2o+wxGhaIr93PIRwBPSByMPvqZFYycd ..
n2gf24JJtwsff2yYRRpVzpr8yKepv3jyAbmQCILKTUakvabyiBPxpUYH9nHsXo5C
5jpmGxGgGPbsqyNP+6Y2DdmiUtKEoQiQjAE4q40s9T/8t+VNVagJqK6R7+zrjMe4
inwkbQkA7CwhWlNPBWAsIf8EwN579OsPrIXknk4i7lia7BIMetrcHxXFqY/qJOpL
@@ -861,7 +861,7 @@ nilE+U/aKB+AmG3VM/pCGZ4KGpDU36SgDZ4nwFo2v0oSI2OITUSzFnROKxWelxkn
3/LoY/4aa+7GJHODW7R4G9oiQx8/Lg==
-----END PRIVATE KEY-----
`
`;
export const mock_csca_sha256_rsapss_3_4096 = `-----BEGIN CERTIFICATE-----
MIIFaTCCA1GgAwIBAgIUBLDEWBLHolBcAfAj5FihkI3d8ccwDQYJKoZIhvcNAQEL
@@ -893,7 +893,7 @@ RhR4lHe8WJpIUrHeFX7Zmo5r6FMP003zrm1uXVI8eSSAwUIsvLTxWMQfwrzxGB7J
lPxSG4KXuoMUvIsDxV8JctXzP5OOf1hY+boqd3n8YeMTWt1qA7TYsKJTsLBU2XO4
HYcuL8c7y01o/R4QfTlXcIofI0EV0yLRo/0/+ynScI43JgEruX5BpN5Kb0Q8rciN
zgPsBxvGQAcHf/j9vPuV9J7Ysm5Ek3mYiHVqkVii8nHwsts2xjDCPUGUc58H
-----END CERTIFICATE-----`
-----END CERTIFICATE-----`;
export const mock_dsc_key_sha256_rsapss_3_4096 = `-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDTP9+SF5DocOTe
@@ -947,7 +947,7 @@ aIVUaJC/GlP6Q7NQ2p/Zm0EGOjRiXK16dgosI5d/oAGTt5ozW1AqCpwxdVV0N8n0
yBJ4blAscsAp0eCKwrIW7bS3fG9eXQhtz+j0iY0tDAk9q98zgtr+/aSRcBsDUZVh
YB+6OfEWTqL61rgUMTbCi6YM5fJToQ==
-----END PRIVATE KEY-----
`
`;
export const mock_dsc_sha256_rsapss_3_4096 = `-----BEGIN CERTIFICATE-----
MIIFwDCCA3SgAwIBAgIUcesdYZnU43PcOUYu85A6aDs81QgwQQYJKoZIhvcNAQEK
@@ -981,7 +981,7 @@ J8NU7jxC7E9p7H+1JEuVkXRzgFRQoHtU5Q6URQ/xsn3/O2RCvMACj1iAOwSgBTSf
hurjlQ1ZjmsOSzcNrXXTLC1eW/ScH1BbUpB1oP3dcuxmkaZBlMUa7iEmXIF+g6av
xqQ2cg1zvTQnb+6nyQIWWAh8zgtvIpOGfaNiTDOZk5oJg/9ozav3BMcWdUQJurn4
mJ6SOQXqPh5uDUG5BwwumHzkITDaftCcO3BJba3GHCMhAXTZ
-----END CERTIFICATE-----`
-----END CERTIFICATE-----`;
export const mock_csca_key_sha256_rsapss_3_3072 = `-----BEGIN PRIVATE KEY-----
MIIG/gIBADANBgkqhkiG9w0BAQEFAASCBugwggbkAgEAAoIBgQDvXdX22QnHkizR
@@ -1022,7 +1022,7 @@ ZcEYXygdgdyqVt2zw04fzfcBUhGfGvQB+jjiVfNB6eqQqVadyeOiB76AAmgChUJD
QrDQmnMXAMmskUtcPDts5z59JmOQ0gYRTjf6IR+yz3QWGLFoTxMM6UNybO5VUoiF
c7n39jd3CSLDOeHAjOt4/13aVyElvKxMSDY9HgjYqlcuBkY/Z3NiDBVrq9BSDUIe
bY2vE1eZZKW5i7g3c6hQ3Zxw
-----END PRIVATE KEY-----`
-----END PRIVATE KEY-----`;
export const mock_csca_sha256_rsapss_3_3072 = `-----BEGIN CERTIFICATE-----
MIIEaTCCAtGgAwIBAgIULeDw7IsLsk6y9yqcAARrKm0qiOkwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
@@ -1048,7 +1048,7 @@ tfVk9Q7vZdBnckNSPQMWWUFmzYwzJrGMKA2Rugev2ZuFqoOVz528LK8p+NMQKfCO
kTtURp/t2fxEqFtIZo8x2LmGidAyoQzHHLBO7Dw1DgNBNgKdVmKkDI5BGirT8gSA
EBBq0cqKIavLC0jvyktLHDgB8OP+fM/cU9Rjmp5GCXjDERDSbp4EmQTGMEtrb4nz
483fjGfLkqBGAxsC7F9cjZMlTHDxFZXxWpoWM4o=
-----END CERTIFICATE-----`
-----END CERTIFICATE-----`;
export const mock_dsc_key_sha256_rsapss_3_3072 = `-----BEGIN PRIVATE KEY-----
MIIG/AIBADANBgkqhkiG9w0BAQEFAASCBuYwggbiAgEAAoIBgQCzn/sT6JxQCJn4
@@ -1089,7 +1089,7 @@ tWut/mKpQzH9OvLHU3cbAquZgdZUVPGsyJIdyGEg6ijmMF0C0lUMq938JILSxCXQ
WAdVlGg6nRMqEMdgUHcX/M9LCpH5HdRVR7vE1BZ+KBpHCrUBNnpKGjAB3BIE7Lx6
N++yqdDF4aI9k+D8l5YVh5+x0vF0o38TDwGjCRjV0RN3XSNh4T3rSds6kVZixYXS
/pE7Qvc1Voct0h8T4dQ0zA==
-----END PRIVATE KEY-----`
-----END PRIVATE KEY-----`;
export const mock_dsc_sha256_rsapss_3_3072 = `-----BEGIN CERTIFICATE-----
MIIEwDCCAvSgAwIBAgIUJ0ZUVWmsXZwHvjP+PmM4YQ5mEb4wQQYJKoZIhvcNAQEK
MDSgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQMEAgEF
@@ -1117,7 +1117,7 @@ wpvVlQCy3DmQ6We1uJFRCcMn3Q+j5pj1YQJxmWjljyJPuF07g7m88npBuGcDnpxY
EIVsQptX3LYy5/0l+zZbkGr//soirv7HlQREN8lsSZtvBepkNyZafg9KasxynDbB
QSwFfauMiF/q99reqMmst0BCBe77lXb8/ParwbqayowiJmNjcSvJeTpVG3rz6nYK
ruZ86kNVDqbSZ6qZjjQoMrLvKQg=
-----END CERTIFICATE-----`
-----END CERTIFICATE-----`;
export const mock_dsc_sha256_rsapss_4096 = `-----BEGIN CERTIFICATE-----
MIIEXTCCAhGgAwIBAgIUdS5K/Y5Ty0C8hDFibjmvBeQr4SgwQQYJKoZIhvcNAQEK
@@ -1244,27 +1244,229 @@ d+9Msdsovrc=
-----END CERTIFICATE-----
`;
export const mock_dsc_key_sha256_brainpoolP256r1 = `-----BEGIN EC PRIVATE KEY-----
MHgCAQEEICM/qGkSEYZJeejSAl3to/52G9Vw+GDKdvw2BA4Hq4TRoAsGCSskAwMC
CAEBB6FEA0IABCga+ftPaAL6Bljws48myO1IDRDjaBkyFR3W/esrhP2pb3poTpqd
KDjKkI9hUU1t3cllGYBP4UzL9IUhe4J7I6s=
export const mock_dsc_key_sha1_brainpoolP224r1 = `-----BEGIN EC PRIVATE KEY-----
MGwCAQEEHEtm6OSi3EClphbb0ovVMLNX6SCQ/ZpYsFTjlnqgCwYJKyQDAwIIAQEF
oTwDOgAEb8kcLsVLjpC1RWAjA/lRTHP2HVdW1ntmtfo1g2R6E6NkgLetsRXxc8Sn
CJ71v4bL9/50ksOiv+U=
-----END EC PRIVATE KEY-----
`;
export const mock_dsc_sha1_brainpoolP224r1 = `-----BEGIN CERTIFICATE-----
MIIBzTCCAX2gAwIBAgIUL2Uxhvbe1w8fdNbH+/nFp0LvkEYwCQYHKoZIzj0EATBF
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMB4XDTI0MTIzMDA4NDQ0MVoXDTI1MTIzMDA4
NDQ0MVowRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNV
BAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDBSMBQGByqGSM49AgEGCSskAwMC
CAEBBQM6AARvyRwuxUuOkLVFYCMD+VFMc/YdV1bWe2a1+jWDZHoTo2SAt62xFfFz
xKcInvW/hsv3/nSSw6K/5aNTMFEwHQYDVR0OBBYEFHWg+dJpv6bTRvEWrInb/XtX
XIzPMB8GA1UdIwQYMBaAFHWg+dJpv6bTRvEWrInb/XtXXIzPMA8GA1UdEwEB/wQF
MAMBAf8wCQYHKoZIzj0EAQM/ADA8Ahx0BuqVqweU/EHvq42lTIH6ku+wPMoqvUL/
jnD0AhwDAIPS8xytmOiI0MuVj3kwdnzTLdsGslSkmj8l
-----END CERTIFICATE-----
`;
export const mock_dsc_key_sha224_braipoolP224r1 = `-----BEGIN EC PRIVATE KEY-----
MGwCAQEEHD8zMUlakQzf4dhsIN/RlRKZqRRPX+y2LJj/6OWgCwYJKyQDAwIIAQEF
oTwDOgAEVhYeSwufAC+rdeIw8skbC2bwM3g7giuR+5vl0brGHgiEIaUr33msAPHz
epGlvTkSRQz+nOWMogI=
-----END EC PRIVATE KEY-----`;
export const mock_dsc_sha224_brainpoolP224r1 = `-----BEGIN CERTIFICATE-----
MIIB0DCCAX6gAwIBAgIUKS+C9XWWr12MLB1+rcVEaYGW53UwCgYIKoZIzj0EAwEw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNTAxMDcwNzUxMDJaFw0yNjAxMDcw
NzUxMDJaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwUjAUBgcqhkjOPQIBBgkrJAMD
AggBAQUDOgAEVhYeSwufAC+rdeIw8skbC2bwM3g7giuR+5vl0brGHgiEIaUr33ms
APHzepGlvTkSRQz+nOWMogKjUzBRMB0GA1UdDgQWBBS7hFp/MRDFZ//5GxYHnpM+
N8mqKTAfBgNVHSMEGDAWgBS7hFp/MRDFZ//5GxYHnpM+N8mqKTAPBgNVHRMBAf8E
BTADAQH/MAoGCCqGSM49BAMBA0AAMD0CHQCT+jX3mCRjmvdXO2HKlb9faeYgKfiX
frIJV5mBAhwEqIQRW2USNItxRt1iTO69eBj/20q67UOhDgK2
-----END CERTIFICATE-----`;
export const mock_dsc_key_sha256_brainpoolP224r1 = `-----BEGIN EC PRIVATE KEY-----
MGwCAQEEHEtm6OSi3EClphbb0ovVMLNX6SCQ/ZpYsFTjlnqgCwYJKyQDAwIIAQEF
oTwDOgAEb8kcLsVLjpC1RWAjA/lRTHP2HVdW1ntmtfo1g2R6E6NkgLetsRXxc8Sn
CJ71v4bL9/50ksOiv+U=
-----END EC PRIVATE KEY-----
`;
export const mock_dsc_sha256_brainpoolP224r1 = `-----BEGIN CERTIFICATE-----
MIIB0DCCAX6gAwIBAgIUVaUBruPv+13YqSDtb28faYlca1UwCgYIKoZIzj0EAwIw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMzAxNDA2NTZaFw0yNTEyMzAx
NDA2NTZaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwUjAUBgcqhkjOPQIBBgkrJAMD
AggBAQUDOgAEb8kcLsVLjpC1RWAjA/lRTHP2HVdW1ntmtfo1g2R6E6NkgLetsRXx
c8SnCJ71v4bL9/50ksOiv+WjUzBRMB0GA1UdDgQWBBR1oPnSab+m00bxFqyJ2/17
V1yMzzAfBgNVHSMEGDAWgBR1oPnSab+m00bxFqyJ2/17V1yMzzAPBgNVHRMBAf8E
BTADAQH/MAoGCCqGSM49BAMCA0AAMD0CHQCXfviMoPED3c43XbavcZkccHVwxOYq
aUpntBqzAhwqxYeED8F9yQVTF3NWcAd1kmySSE79HoCpjdTZ
-----END CERTIFICATE-----
`;
export const mock_dsc_key_sha256_brainpoolP256r1 = `-----BEGIN EC PRIVATE KEY-----
MHgCAQEEIHX6m0IJHboaDf9ps1k41yUU1WmNW9bU/IOXWW0qJAFCoAsGCSskAwMC
CAEBB6FEA0IABFVMiAVBX0noMTcHttSx+StzGj9l23Zg4RAWI3DpaFFiePOvNjAl
lmufhS8tfngmKha/esLfQi4S9fWeosnB21g=
-----END EC PRIVATE KEY-----
`;
export const mock_dsc_sha256_brainpoolP256r1 = `-----BEGIN CERTIFICATE-----
MIICDzCCAbagAwIBAgIUcNlflnEgBabRuI8TtmhfuXeBDxAwCgYIKoZIzj0EAwIw
ZjELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5MRUw
EwYDVQQKDAxPcmdhbml6YXRpb24xDTALBgNVBAsMBFVuaXQxEjAQBgNVBAMMCW1v
Y2tfY3NjYTAeFw0yNDEwMDMxODE2MzFaFw0yNTEwMDMxODE2MzFaMGUxCzAJBgNV
BAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0eTEVMBMGA1UECgwM
T3JnYW5pemF0aW9uMQ0wCwYDVQQLDARVbml0MREwDwYDVQQDDAhtb2NrX2RzYzBa
MBQGByqGSM49AgEGCSskAwMCCAEBBwNCAARcehJ7rf3trDknfb3agrcH08G7q0lZ
GL6fpY3beLTxeJMFF36REb8HLnOUFGw78hfPH8etWuA9H7HVZ/vB8Cd8o0IwQDAd
BgNVHQ4EFgQUQE/6d9aMviaMEi9k91hdsVguoekwHwYDVR0jBBgwFoAUXOj0kKh6
5e3xwozKdrj0y/kxpVkwCgYIKoZIzj0EAwIDRwAwRAIgfcPQcDu6hK7ad5EM1Owf
hlAwf+ljOVwK1ZhDh5lJLicCIEJdrWnH+dUOBL+NecPbLmcFVBCelST9iNCUXTKD
CLpT
MIICDTCCAbOgAwIBAgIUKQXq4OH8wTSY9vXu3xqscfhTKKEwCgYIKoZIzj0EAwIw
ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDTALBgNVBAcMBFRlc3QxETAP
BgNVBAoMCFRlc3QgT3JnMRAwDgYDVQQLDAdUZXN0IENBMRIwEAYDVQQDDAltb2Nr
X2NzY2EwHhcNMjUwMTA2MTkyNzE4WhcNMjYwMTA2MTkyNzE4WjBkMQswCQYDVQQG
EwJVUzENMAsGA1UECAwEVGVzdDENMAsGA1UEBwwEVGVzdDERMA8GA1UECgwIVGVz
dCBPcmcxETAPBgNVBAsMCFRlc3QgRFNDMREwDwYDVQQDDAhtb2NrX2RzYzBaMBQG
ByqGSM49AgEGCSskAwMCCAEBBwNCAARVTIgFQV9J6DE3B7bUsfkrcxo/Zdt2YOEQ
FiNw6WhRYnjzrzYwJZZrn4UvLX54JioWv3rC30IuEvX1nqLJwdtYo0IwQDAdBgNV
HQ4EFgQUdrAlgo3oxQVU+C98YX/2WHVrPbgwHwYDVR0jBBgwFoAUkHkWG0fyqmbh
JHCyXhS947uidd0wCgYIKoZIzj0EAwIDSAAwRQIgS7zlTvVsF/wgB3yGB0koxZ4B
3tFJX5wDW2DRO2xqgAECIQCL7Tw62w6qYH6Isr9FiB5xoL4s/CnsOK+pJEUWevdu
gg==
-----END CERTIFICATE-----
`;
export const mock_dsc_key_sha384_brainpoolP256r1 = `-----BEGIN EC PRIVATE KEY-----
MHgCAQEEIIhHbA4GKMOiNXQcXTiFlQUX2YFKz5U/Ya+vQa/YFo6foAsGCSskAwMC
CAEBB6FEA0IABKje0Lfu0ACxcGqEJc2vF6AYckbw9LaoHIKRyM6ko91AFuNhEIsx
pUF1FV+lornr3u0I7bOxL4PlOD+nZuRXGQE=
-----END EC PRIVATE KEY-----
`;
export const mock_dsc_sha384_brainpoolP256r1 = `-----BEGIN CERTIFICATE-----
MIIB3zCCAYagAwIBAgIUNxoAJFWOPOCE9KOmtQZpg4NiEzMwCgYIKoZIzj0EAwMw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMjgwNjE0MTZaFw0yNTEyMjgw
NjE0MTZaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwWjAUBgcqhkjOPQIBBgkrJAMD
AggBAQcDQgAEqN7Qt+7QALFwaoQlza8XoBhyRvD0tqgcgpHIzqSj3UAW42EQizGl
QXUVX6Wiueve7Qjts7Evg+U4P6dm5FcZAaNTMFEwHQYDVR0OBBYEFHB+vSzRl9Vy
UedDOcm9V+sbVYlLMB8GA1UdIwQYMBaAFHB+vSzRl9VyUedDOcm9V+sbVYlLMA8G
A1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwMDRwAwRAIgFv62dVvKdRlqCcRfQdax
iSfNPb3k7L2E0ETWSZ0KLvICIC8csz7X6VOTuVspKl1YXlBM6hOx7gTVdaGKmTR2
WtFT
-----END CERTIFICATE-----
`;
export const mock_dsc_key_sha512_brainpoolP256r1 = `-----BEGIN EC PRIVATE KEY-----
MHgCAQEEIFuQVhd8HfMpFLdTH60+UA1HfePAQkfeaGH6V9FJe5kioAsGCSskAwMC
CAEBB6FEA0IABCAx2ey4sj3xDzMbrJyjyINrSw57z98QcllbStcRHCz2YIfUUvsh
KwkgnEMAWec4iy3jeZ8yeLcoGk0fi6iCoLk=
-----END EC PRIVATE KEY-----
`;
export const mock_dsc_sha512_brainpoolP256r1 = `-----BEGIN CERTIFICATE-----
MIIB3zCCAYagAwIBAgIUQYSjqrXJx+UTzjryNw2jl8a8bUowCgYIKoZIzj0EAwQw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMjgwODU5NDFaFw0yNTEyMjgw
ODU5NDFaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwWjAUBgcqhkjOPQIBBgkrJAMD
AggBAQcDQgAEIDHZ7LiyPfEPMxusnKPIg2tLDnvP3xByWVtK1xEcLPZgh9RS+yEr
CSCcQwBZ5ziLLeN5nzJ4tygaTR+LqIKguaNTMFEwHQYDVR0OBBYEFDxCzGkoR6xw
Im2XGg/24tJ+2fgyMB8GA1UdIwQYMBaAFDxCzGkoR6xwIm2XGg/24tJ+2fgyMA8G
A1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwQDRwAwRAIgPC4h2/aUem5OMnwMy42R
9j/NhYacXZGKXZv5KVBq5o4CIE/LcOS7bs7K3uNOdFxdJDCpK56YGV4H3O1paLpt
VqPW
-----END CERTIFICATE-----
`;
export const mock_dsc_key_sha256_secp384r1 = `-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDBZthN5/vhpqE/ALHj35A/pMkfSDRxFKKweTYs2IxR0eW6RJQlZhdgk
TGP7rQ4EKF6gBwYFK4EEACKhZANiAASsl16vufqKa/qdJWIEDO5no2useouKh4Zk
AdtBf3fWjDnsT3J9ulxe0Ep+QbC8010o3dGQZL5UqwzoarLGrFentQ4wTJYzLXX2
VHrLCyDjwswia1U3+I9ZYLp1TA9+88A=
-----END EC PRIVATE KEY-----
`;
export const mock_dsc_sha256_secp384r1 = `-----BEGIN CERTIFICATE-----
MIICHDCCAaKgAwIBAgIUIxGxDq5DcnphGZhSQNaAMWC5WtcwCgYIKoZIzj0EAwIw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMjgwNTMwMzlaFw0yNTEyMjgw
NTMwMzlaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwdjAQBgcqhkjOPQIBBgUrgQQA
IgNiAASsl16vufqKa/qdJWIEDO5no2useouKh4ZkAdtBf3fWjDnsT3J9ulxe0Ep+
QbC8010o3dGQZL5UqwzoarLGrFentQ4wTJYzLXX2VHrLCyDjwswia1U3+I9ZYLp1
TA9+88CjUzBRMB0GA1UdDgQWBBQuToV7daaeM2l+EdWsqXX4NP1gFjAfBgNVHSME
GDAWgBQuToV7daaeM2l+EdWsqXX4NP1gFjAPBgNVHRMBAf8EBTADAQH/MAoGCCqG
SM49BAMCA2gAMGUCMFEUPb/G0QxEiAW0d1S7njA4UPPtgugQ44PDjWhFrwEowtEv
gmDwQUgL/nKb+7GsSQIxANABnyvZSR9heu9rqqYxeW/0eGoQoDnSiZowdf7Z6fJP
aiTuTmjxvd1KKxrCkmuSDg==
-----END CERTIFICATE-----
`;
export const mock_dsc_key_sha384_brainpoolP384r1 = `-----BEGIN EC PRIVATE KEY-----
MIGoAgEBBDAAqX21j3nsvbpheKxpL3Vbj9Q5rkMqZ1LTVOpykpFezXH8R+d9tYgl
lMBGmlszFJSgCwYJKyQDAwIIAQELoWQDYgAEf0p2YN3Lru5iZ8KRhZfUthvwBa9u
SZgsKlmeBE7epzdpJvkGL3QSHO2GiF7Nv8MYEerqpwyynlAL9YK8HAqAXOoOa+rP
RvG+mFXRYyRZTMwIH5/ULI29H+tLqsRejx4x
-----END EC PRIVATE KEY-----
`;
export const mock_dsc_sha384_brainpoolP384r1 = `-----BEGIN CERTIFICATE-----
MIICHzCCAaagAwIBAgIUIWM2gNwyhyOd0Tv2h8Hm63b/s54wCgYIKoZIzj0EAwMw
RTELMAkGA1UEBhMCSU4xEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMjcwOTQzMjBaFw0yNTEyMjcw
OTQzMjBaMEUxCzAJBgNVBAYTAklOMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwejAUBgcqhkjOPQIBBgkrJAMD
AggBAQsDYgAEf0p2YN3Lru5iZ8KRhZfUthvwBa9uSZgsKlmeBE7epzdpJvkGL3QS
HO2GiF7Nv8MYEerqpwyynlAL9YK8HAqAXOoOa+rPRvG+mFXRYyRZTMwIH5/ULI29
H+tLqsRejx4xo1MwUTAdBgNVHQ4EFgQUpCaQbwuQL/GaEmjSH4oVu8zku44wHwYD
VR0jBBgwFoAUpCaQbwuQL/GaEmjSH4oVu8zku44wDwYDVR0TAQH/BAUwAwEB/zAK
BggqhkjOPQQDAwNnADBkAjArBhymHpn9modIUw0Q/t3wxyzGYO9UpuiAxJiiRWVM
SduwTA4zUXYzfQUEn50j4lQCMHbwK7l1rwHW0FlpAMG3GDFgTNUaCU2I/m3J4A/E
bKeq3jWgsSb2o7VSgneDGG70Qw==
-----END CERTIFICATE-----
`;
export const mock_dsc_key_sha512_brainpoolP384r1 = `-----BEGIN EC PRIVATE KEY-----
MIGoAgEBBDB4JkHrXVXl2oWIH04Wh0ERPrGi+oW6Gm4Qs+QMlzMlZFz/pGn9BbFo
VwHIejJ8fuWgCwYJKyQDAwIIAQELoWQDYgAEgFY8mpSYBoiXECveGnKHO/9PW96k
WT80fBf3/tz8vytQGhLzqFS4kcxSsoO9lJXnfLk+PTqKyHGX8wPAqD9MvGcD8pj1
uvEviUV7Hp99wos7JXGGdm8koJhAvfGSt6N3
-----END EC PRIVATE KEY-----
`;
export const mock_dsc_sha512_brainpoolP384r1 = `-----BEGIN CERTIFICATE-----
MIICIDCCAaagAwIBAgIUUxZNjQROjb8L3QFE3qKEAOuGA/4wCgYIKoZIzj0EAwQw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMjgxMDA3MDdaFw0yNTEyMjgx
MDA3MDdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwejAUBgcqhkjOPQIBBgkrJAMD
AggBAQsDYgAEgFY8mpSYBoiXECveGnKHO/9PW96kWT80fBf3/tz8vytQGhLzqFS4
kcxSsoO9lJXnfLk+PTqKyHGX8wPAqD9MvGcD8pj1uvEviUV7Hp99wos7JXGGdm8k
oJhAvfGSt6N3o1MwUTAdBgNVHQ4EFgQUUgkQRw5jvunoflxxAvX5Yc+ROgswHwYD
VR0jBBgwFoAUUgkQRw5jvunoflxxAvX5Yc+ROgswDwYDVR0TAQH/BAUwAwEB/zAK
BggqhkjOPQQDBANoADBlAjEAhtyXbjYqxVBT4KonoZcYciftQkRt+0DxBnPmRZ52
d67SbyA9LP/7XDTg8qw++aPyAjAFYTG7tu/EGBqWfvSCjEo0aK9ZS/eS5HZoTfs7
dzuXqOBuBj1L+HpiiBobsDhL63c=
-----END CERTIFICATE-----
`;
export const mock_dsc_key_sha512_brainpoolP512r1 = `-----BEGIN EC PRIVATE KEY-----
MIHaAgEBBEBsh1A9ArliqvxSQg7Z4u9XszaGEJTw9qPD52QSVG9qWN7zfnl4xWmD
m7ZCM00Lc2it0orK3FjymVEPr7GOcLgPoAsGCSskAwMCCAEBDaGBhQOBggAEjJkR
N4I/rAdmNOyUfmz/xAZ8rhLQlKYk8qwdQg3XrW0r9VbXTRkdnJxZLo8m/PH9AlFL
qHdloVKLJp+JkITdYWuLbDn+Y6wGUCsFLCfJR1YRByP5L0+gT4LcFlotLDmRm46B
44q5Et+aQIimslTS9KAK6VlSSswSEaG2LqzSAD0=
-----END EC PRIVATE KEY-----
`;
export const mock_dsc_sha512_brainpoolP512r1 = `-----BEGIN CERTIFICATE-----
MIICYzCCAcigAwIBAgIUAwDW2UZPk3oy12xQCOrtAi4J8dswCgYIKoZIzj0EAwQw
RTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGElu
dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDEyMzAxNDUyMTdaFw0yNTEyMzAx
NDUyMTdaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD
VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwgZswFAYHKoZIzj0CAQYJKyQD
AwIIAQENA4GCAASMmRE3gj+sB2Y07JR+bP/EBnyuEtCUpiTyrB1CDdetbSv1VtdN
GR2cnFkujyb88f0CUUuod2WhUosmn4mQhN1ha4tsOf5jrAZQKwUsJ8lHVhEHI/kv
T6BPgtwWWi0sOZGbjoHjirkS35pAiKayVNL0oArpWVJKzBIRobYurNIAPaNTMFEw
HQYDVR0OBBYEFGNz0nQzf/S2dvSrGKeczYkAapabMB8GA1UdIwQYMBaAFGNz0nQz
f/S2dvSrGKeczYkAapabMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwQDgYgA
MIGEAkBvgsKebJL2PQOXy3KWDvb50ygqXAXItDbbqLqxE+7h7zswDiqQz/tDtDeG
tGGbBQIiYYwa1WlqaTJA+AjUpsZCAkBW+Z7PiQJE4DNms8za0bzom7u5kaHGaOGU
fRSx8q4PN04hIQfS8Rm4/1Zg8VmHIQ4kdnYC4WLQgXOmshSS8LTi
-----END CERTIFICATE-----
`;
@@ -1400,4 +1602,4 @@ cIlCXtLAlhwxvkvq6fXlDHODihiBrcmRBxz08o+IXvjgBYlfHWP5iDS4RO0lzId4
JYSWvyeHGutMDlIMuw5KEE1kVxR2XXcZypc9dWHGaI6MrYwpmmvTB6oZg11FEZzm
S8w23130L6pAB1EjCC8lUQubEkgDZ0bfy4UxpkOiqctzYdakvgo+zOwpORhN/Wxp
Vnmv
-----END CERTIFICATE-----`;
-----END CERTIFICATE-----`;

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHgCAQEEICM/qGkSEYZJeejSAl3to/52G9Vw+GDKdvw2BA4Hq4TRoAsGCSskAwMC
CAEBB6FEA0IABCga+ftPaAL6Bljws48myO1IDRDjaBkyFR3W/esrhP2pb3poTpqd
KDjKkI9hUU1t3cllGYBP4UzL9IUhe4J7I6s=
MHgCAQEEIG7/AK93yICDHfbPdYZLl6IZVVAzUivyL2xkOF4rfQ+doAsGCSskAwMC
CAEBB6FEA0IABJtrheiW+wzPd4/oYBmXhVUsPD2glTeJdS7u98bn7M4beD7zOaFI
CnVwJaASnynMHfsgUK5t3s0JaL5lS6LyUFY=
-----END EC PRIVATE KEY-----

View File

@@ -1,14 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICITCCAcigAwIBAgIUP/OaQj/tscHEXoAjzLB9EHU9/aAwCgYIKoZIzj0EAwIw
ZjELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5MRUw
EwYDVQQKDAxPcmdhbml6YXRpb24xDTALBgNVBAsMBFVuaXQxEjAQBgNVBAMMCW1v
Y2tfY3NjYTAeFw0yNDEwMDMxODE2MTVaFw0yNTEwMDMxODE2MTVaMGYxCzAJBgNV
BAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0eTEVMBMGA1UECgwM
T3JnYW5pemF0aW9uMQ0wCwYDVQQLDARVbml0MRIwEAYDVQQDDAltb2NrX2NzY2Ew
WjAUBgcqhkjOPQIBBgkrJAMDAggBAQcDQgAEKBr5+09oAvoGWPCzjybI7UgNEONo
GTIVHdb96yuE/alvemhOmp0oOMqQj2FRTW3dyWUZgE/hTMv0hSF7gnsjq6NTMFEw
HQYDVR0OBBYEFFzo9JCoeuXt8cKMyna49Mv5MaVZMB8GA1UdIwQYMBaAFFzo9JCo
euXt8cKMyna49Mv5MaVZMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAw
RAIgCY6ffz2o3IQ+xEORM7nmyhqthpij1DxWDwwliOIXbM8CIGhHsa8fF9gd3VPA
4n96mZ9PcVhYg5xT5z2g51LwsFsx
MIICHjCCAcSgAwIBAgIUGtUi62MiKpDflwXLOYR37+jTk7YwCgYIKoZIzj0EAwIw
ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDTALBgNVBAcMBFRlc3QxETAP
BgNVBAoMCFRlc3QgT3JnMRAwDgYDVQQLDAdUZXN0IENBMRIwEAYDVQQDDAltb2Nr
X2NzY2EwHhcNMjUwMTA2MTkyNzE4WhcNMzUwMTA0MTkyNzE4WjBkMQswCQYDVQQG
EwJVUzENMAsGA1UECAwEVGVzdDENMAsGA1UEBwwEVGVzdDERMA8GA1UECgwIVGVz
dCBPcmcxEDAOBgNVBAsMB1Rlc3QgQ0ExEjAQBgNVBAMMCW1vY2tfY3NjYTBaMBQG
ByqGSM49AgEGCSskAwMCCAEBBwNCAASba4XolvsMz3eP6GAZl4VVLDw9oJU3iXUu
7vfG5+zOG3g+8zmhSAp1cCWgEp8pzB37IFCubd7NCWi+ZUui8lBWo1MwUTAdBgNV
HQ4EFgQUkHkWG0fyqmbhJHCyXhS947uidd0wHwYDVR0jBBgwFoAUkHkWG0fyqmbh
JHCyXhS947uidd0wDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNIADBFAiEA
mb7Eh5jSx69wCOsW7vs+53zb6/tZ6xl2mDYTqjywFMoCIHYPU8wXexgyQ+CcO0sj
wXd8ZV3f9zEb1h/UJ+29Gx8R
-----END CERTIFICATE-----

View File

@@ -1,5 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHgCAQEEIDsVrfRbMQvO91NNpswhfUCnJ071zdfZHs5ao8iZ/JvXoAsGCSskAwMC
CAEBB6FEA0IABFx6Enut/e2sOSd9vdqCtwfTwburSVkYvp+ljdt4tPF4kwUXfpER
vwcuc5QUbDvyF88fx61a4D0fsdVn+8HwJ3w=
MHgCAQEEIHX6m0IJHboaDf9ps1k41yUU1WmNW9bU/IOXWW0qJAFCoAsGCSskAwMC
CAEBB6FEA0IABFVMiAVBX0noMTcHttSx+StzGj9l23Zg4RAWI3DpaFFiePOvNjAl
lmufhS8tfngmKha/esLfQi4S9fWeosnB21g=
-----END EC PRIVATE KEY-----

View File

@@ -1,14 +1,14 @@
-----BEGIN CERTIFICATE-----
MIICDzCCAbagAwIBAgIUcNlflnEgBabRuI8TtmhfuXeBDxAwCgYIKoZIzj0EAwIw
ZjELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVN0YXRlMQ0wCwYDVQQHDARDaXR5MRUw
EwYDVQQKDAxPcmdhbml6YXRpb24xDTALBgNVBAsMBFVuaXQxEjAQBgNVBAMMCW1v
Y2tfY3NjYTAeFw0yNDEwMDMxODE2MzFaFw0yNTEwMDMxODE2MzFaMGUxCzAJBgNV
BAYTAlVTMQ4wDAYDVQQIDAVTdGF0ZTENMAsGA1UEBwwEQ2l0eTEVMBMGA1UECgwM
T3JnYW5pemF0aW9uMQ0wCwYDVQQLDARVbml0MREwDwYDVQQDDAhtb2NrX2RzYzBa
MBQGByqGSM49AgEGCSskAwMCCAEBBwNCAARcehJ7rf3trDknfb3agrcH08G7q0lZ
GL6fpY3beLTxeJMFF36REb8HLnOUFGw78hfPH8etWuA9H7HVZ/vB8Cd8o0IwQDAd
BgNVHQ4EFgQUQE/6d9aMviaMEi9k91hdsVguoekwHwYDVR0jBBgwFoAUXOj0kKh6
5e3xwozKdrj0y/kxpVkwCgYIKoZIzj0EAwIDRwAwRAIgfcPQcDu6hK7ad5EM1Owf
hlAwf+ljOVwK1ZhDh5lJLicCIEJdrWnH+dUOBL+NecPbLmcFVBCelST9iNCUXTKD
CLpT
MIICDTCCAbOgAwIBAgIUKQXq4OH8wTSY9vXu3xqscfhTKKEwCgYIKoZIzj0EAwIw
ZDELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFRlc3QxDTALBgNVBAcMBFRlc3QxETAP
BgNVBAoMCFRlc3QgT3JnMRAwDgYDVQQLDAdUZXN0IENBMRIwEAYDVQQDDAltb2Nr
X2NzY2EwHhcNMjUwMTA2MTkyNzE4WhcNMjYwMTA2MTkyNzE4WjBkMQswCQYDVQQG
EwJVUzENMAsGA1UECAwEVGVzdDENMAsGA1UEBwwEVGVzdDERMA8GA1UECgwIVGVz
dCBPcmcxETAPBgNVBAsMCFRlc3QgRFNDMREwDwYDVQQDDAhtb2NrX2RzYzBaMBQG
ByqGSM49AgEGCSskAwMCCAEBBwNCAARVTIgFQV9J6DE3B7bUsfkrcxo/Zdt2YOEQ
FiNw6WhRYnjzrzYwJZZrn4UvLX54JioWv3rC30IuEvX1nqLJwdtYo0IwQDAdBgNV
HQ4EFgQUdrAlgo3oxQVU+C98YX/2WHVrPbgwHwYDVR0jBBgwFoAUkHkWG0fyqmbh
JHCyXhS947uidd0wCgYIKoZIzj0EAwIDSAAwRQIgS7zlTvVsF/wgB3yGB0koxZ4B
3tFJX5wDW2DRO2xqgAECIQCL7Tw62w6qYH6Isr9FiB5xoL4s/CnsOK+pJEUWevdu
gg==
-----END CERTIFICATE-----

View File

@@ -0,0 +1,79 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
75:2e:4a:fd:8e:53:cb:40:bc:84:31:62:6e:39:af:05:e4:2b:e1:28
Signature Algorithm: rsassaPss
Hash Algorithm: sha256
Mask Algorithm: mgf1 with sha256
Salt Length: 0x20
Trailer Field: 0x01 (default)
Issuer: CN=Mock CSCA
Validity
Not Before: Jun 29 15:43:50 2024 GMT
Not After : Jun 28 15:43:50 2029 GMT
Subject: CN=Mock DSC
Subject Public Key Info:
Public Key Algorithm: rsassaPss
Public-Key: (2048 bit)
Modulus:
00:f0:37:bd:56:86:bf:3a:38:8c:ab:2c:54:7c:db:
fc:e7:1e:97:e2:b6:4d:19:f0:51:3b:56:31:e7:70:
3e:3e:9c:c5:a8:80:77:1f:d0:a4:13:c3:57:b9:43:
20:05:70:58:61:11:08:99:2b:28:5e:a6:cc:37:06:
47:e7:3e:00:d6:e6:31:8f:6c:5b:e9:52:ad:24:8a:
d1:5c:9c:44:a9:aa:89:28:8e:01:82:c6:7f:bd:0e:
c2:af:a5:ab:11:2e:de:81:5e:5c:b2:c9:ec:2e:a8:
5d:66:98:c8:35:04:07:c9:6a:b3:cb:3c:70:dc:5b:
fe:e5:1c:a9:89:2e:19:ac:ae:fe:9b:b9:7f:62:f1:
5c:cd:bf:89:e6:98:75:f5:0b:40:f9:64:58:08:64:
6e:ce:20:11:15:56:35:f9:d4:15:12:b8:81:81:4b:
11:66:93:e9:f0:07:21:a1:e7:9d:14:8e:26:de:f1:
42:5f:78:16:9b:85:08:bc:c1:ed:a8:20:fe:3c:2e:
3a:67:d5:41:2f:08:49:d6:b6:3b:cb:83:68:80:dd:
03:6e:77:e8:77:fc:f6:f0:d9:5d:9d:04:6e:83:ea:
26:80:d8:4f:70:46:8e:83:98:44:e6:ab:8b:2c:20:
25:cd:41:dc:91:f1:0d:d5:f8:c3:91:4a:81:8d:37:
3c:87
Exponent: 65537 (0x10001)
No PSS parameter restrictions
X509v3 extensions:
X509v3 Subject Key Identifier:
A1:4B:DD:6B:CA:C6:78:2A:75:65:FD:D3:D4:0B:B2:BE:1D:FC:90:D5
X509v3 Authority Key Identifier:
3C:A5:DF:44:8B:1F:18:A9:1F:AA:66:4C:26:21:EB:88:15:01:7D:BB
Signature Algorithm: rsassaPss
Signature Value:
Hash Algorithm: sha256
Mask Algorithm: mgf1 with sha256
Salt Length: 0x20
Trailer Field: 0x01 (default)
0b:2c:a3:44:0a:1e:d5:df:21:cc:cb:4d:4b:ec:2f:4e:ed:28:
29:0d:93:6c:8d:5d:a5:82:8c:a8:47:53:c4:df:81:23:12:b1:
6e:58:9e:08:34:e4:c7:67:37:56:69:41:40:58:e9:7f:87:3a:
46:aa:46:d1:2a:a2:86:d3:da:e9:73:fd:65:48:98:8e:b1:e0:
4c:67:9b:79:0f:da:5d:2f:36:e2:f0:80:a2:c0:ad:e3:9b:04:
a9:34:88:57:9b:81:bc:1a:8a:0c:d7:70:2f:53:4f:f2:5c:62:
9e:e3:46:2e:bf:bb:9b:4c:19:d6:ca:0b:42:1e:77:b4:ff:c6:
ed:25:3c:ab:56:7f:64:88:6e:60:c0:57:f7:42:ec:0e:54:78:
87:c7:62:3c:0b:d8:26:11:64:6f:af:ff:af:1d:e7:80:b1:a6:
4a:24:1d:6e:d6:3d:12:19:0d:86:c3:f1:da:d3:a3:f1:e0:8a:
72:05:a1:d5:31:18:96:5c:17:09:c7:d6:f9:fb:3d:c0:b0:f4:
97:ce:de:45:45:b9:6f:3b:81:1f:d8:e8:ce:91:1b:77:61:c2:
9f:bc:4b:b0:b9:fc:b2:39:8e:e0:ff:10:73:3c:74:d1:7f:9e:
63:81:64:8c:c9:38:c3:e1:c3:c2:89:0f:5c:f4:d5:c8:15:f9:
65:7e:29:aa:c1:c7:47:3f:ba:b8:b4:92:63:fa:ba:1d:37:1d:
1c:50:9a:72:cd:55:11:32:38:8b:d5:06:d1:88:d8:e0:0d:c4:
3c:05:0d:be:0c:ff:18:89:fb:2e:36:bf:27:14:87:c2:f2:68:
3d:52:73:a2:9c:f2:66:c5:14:78:3d:46:a5:41:3a:c9:58:00:
df:5f:c4:d7:e7:62:27:94:bf:64:a1:c7:9b:29:7c:9d:ff:c7:
d6:1c:d4:97:da:3f:4b:3f:fb:a4:2a:d9:1b:85:9f:51:8f:22:
7e:08:11:78:72:e8:2d:64:85:17:c4:b8:26:a0:4a:ca:44:6e:
eb:b7:db:91:72:de:e7:65:60:9d:84:af:e8:65:71:bd:fd:4d:
ee:68:43:3b:9d:22:15:83:43:5c:87:74:4a:02:fe:69:d4:f2:
96:a2:2c:af:99:79:05:0c:3c:e2:f7:f6:9b:e3:ce:f3:15:f6:
3c:f1:53:3b:a9:14:b2:2b:eb:f5:de:5c:52:05:61:76:e0:df:
25:63:da:b3:87:77:14:a7:66:b9:2a:a7:51:48:7b:b4:65:99:
72:dc:d7:9c:0d:24:05:55:da:d6:3e:4e:b5:4e:70:fb:5a:a9:
f6:96:ed:bf:f9:1c:8b:63:87:16:7b:cb:5a:cd:67:ce:48:f9:
f0:57:23:a5:51:b4:f9:93

View File

@@ -0,0 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIFCTCCAvGgAwIBAgIUU3HXu3HEmJlh+Cqpae1jkw1k5GAwDQYJKoZIhvcNAQEL
BQAwFDESMBAGA1UEAwwJTW9jayBDU0NBMB4XDTI1MDEwNTEyMTIxMFoXDTM1MDEw
MzEyMTIxMFowFDESMBAGA1UEAwwJTW9jayBDU0NBMIICIjANBgkqhkiG9w0BAQEF
AAOCAg8AMIICCgKCAgEA0m44QfCCuLqxmMJaBfmDK3OdXKN3eNJiB/fcJkTtMinr
beXJgs0GXyS2HJF3LEw5s9yQQlQ+Va6B5+TOWoPdT/pOTJkd6i8/61pkqWZl2CPm
Aglmn50kAb4MFkJlz0/JJg9aFPw8FBITKf+v2GVd3FZV3Tk7ADzJeOaaBsfEaAg2
Q/XFwavDDrfAOhQL0gzrJuiSUwywPt1j6R3imY6Ba2bss0byjddaHdVaKgXJL2pJ
nKXowrB/Q8mDN2NcGgQrGVDU+kUPz3Rq7YkUg0VEzg1PkqgW1pGMnYpLMkUQXBKl
WbsVudmEHKP3ENessZzrB/jbN8SkNv5bZINKx7YzCR6129FX1rpVQ7k8eBt32BG+
8h2gq3mYt4zf3Ge1ii2StnHryjC/XXC/50lhNfHEElT96PaoYhdzdGM5Ao8+NJxi
BRgvE6uTQjGqkIg4qdsHLt2G4FLpV+ieSbSbSTNvR3eY+lJDduCnBbqJhjoiTtAf
w1bSYL06D+gvS1QCqBMGj8dBqGvoI8K0OJYUmkJWBA6MjLKWtRoI0bjOyONWWWjD
HdcHZlYaAN3nfgDNDEsJMnvG/iVWTpOpGd9q9tkfBaYbZVTEUMWY0ME6rtyczr3c
++ix6TIt6hbTFdqmqWgOVBZxHjnNgcw3HMDgnwGCYp4J8BGqVuuw5eTU3Rqy37cC
AwEAAaNTMFEwHQYDVR0OBBYEFNhpgbT96UUf2f2mxDGchFw8sqVqMB8GA1UdIwQY
MBaAFNhpgbT96UUf2f2mxDGchFw8sqVqMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
hvcNAQELBQADggIBAFZogQWujEVZa10UDxM1R8JBxgtzkFDn2SqkxZv9ht1Ux4BH
4EUpFgeRJoOvV9+j4oMGZFfPkaoszbyXhnwHRwlwIbBOXHjS7GJNQI5yMjD+BApA
f56bW/jZ+Sk7xEATQyLDllE9e9YXAsTQ8OsWSdJom4Ka7x3TVKHzqtySzlY8SJaE
mnaZ3TZmGNH8azzt9imlZuRbJQdAI28RQChAMLQM80NXHJTneV5Maeo+fQjyB4Uv
haRDgNreIarPLuuaVsKnPPcPOiZfzqeAeJEaEGwYORrYWrQERqNvcvOW7bAh/JoO
fSTPdgtx3lXcUhgulqseTdddbeCkvmHgbCEjzh7SqFDRdUuL3gNs4fAE9K7z9sA5
g7F2q9kgYDO0b/KvKCh9eWlnotEHd67VMeoCDF183vy0ALeYxdGamt3wuglLUX5v
LhwZ70IzHTHnQ9ctQTQ6dohcgwK4wr0NjhEjC7OAHMRfeF5FQH01Dfs0F7c4gJ6N
HjLmTmceeabvy/LJBlDKrDUg34kEbZ9b+oJoBqld/9pzy22KmMGhj+MB1yfByZnA
wjk9oocrgBncj+s5AtyWy01BGZwmW72WotCdLHnWV+FIJ5ad7hFUFjHD08GnvqVx
ciIgYucmJXri1zIirhnetggSH66eDxeZqxWvxCja9rfOotpVCfdcBmugymgH
-----END CERTIFICATE-----

View File

@@ -0,0 +1 @@
0D8719B1C1968AE52BCA6B5FF0C7195751CFB8E9

View File

@@ -0,0 +1,89 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
53:71:d7:bb:71:c4:98:99:61:f8:2a:a9:69:ed:63:93:0d:64:e4:60
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=Mock CSCA
Validity
Not Before: Jan 5 12:12:10 2025 GMT
Not After : Jan 3 12:12:10 2035 GMT
Subject: CN=Mock CSCA
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
Modulus:
00:d2:6e:38:41:f0:82:b8:ba:b1:98:c2:5a:05:f9:
83:2b:73:9d:5c:a3:77:78:d2:62:07:f7:dc:26:44:
ed:32:29:eb:6d:e5:c9:82:cd:06:5f:24:b6:1c:91:
77:2c:4c:39:b3:dc:90:42:54:3e:55:ae:81:e7:e4:
ce:5a:83:dd:4f:fa:4e:4c:99:1d:ea:2f:3f:eb:5a:
64:a9:66:65:d8:23:e6:02:09:66:9f:9d:24:01:be:
0c:16:42:65:cf:4f:c9:26:0f:5a:14:fc:3c:14:12:
13:29:ff:af:d8:65:5d:dc:56:55:dd:39:3b:00:3c:
c9:78:e6:9a:06:c7:c4:68:08:36:43:f5:c5:c1:ab:
c3:0e:b7:c0:3a:14:0b:d2:0c:eb:26:e8:92:53:0c:
b0:3e:dd:63:e9:1d:e2:99:8e:81:6b:66:ec:b3:46:
f2:8d:d7:5a:1d:d5:5a:2a:05:c9:2f:6a:49:9c:a5:
e8:c2:b0:7f:43:c9:83:37:63:5c:1a:04:2b:19:50:
d4:fa:45:0f:cf:74:6a:ed:89:14:83:45:44:ce:0d:
4f:92:a8:16:d6:91:8c:9d:8a:4b:32:45:10:5c:12:
a5:59:bb:15:b9:d9:84:1c:a3:f7:10:d7:ac:b1:9c:
eb:07:f8:db:37:c4:a4:36:fe:5b:64:83:4a:c7:b6:
33:09:1e:b5:db:d1:57:d6:ba:55:43:b9:3c:78:1b:
77:d8:11:be:f2:1d:a0:ab:79:98:b7:8c:df:dc:67:
b5:8a:2d:92:b6:71:eb:ca:30:bf:5d:70:bf:e7:49:
61:35:f1:c4:12:54:fd:e8:f6:a8:62:17:73:74:63:
39:02:8f:3e:34:9c:62:05:18:2f:13:ab:93:42:31:
aa:90:88:38:a9:db:07:2e:dd:86:e0:52:e9:57:e8:
9e:49:b4:9b:49:33:6f:47:77:98:fa:52:43:76:e0:
a7:05:ba:89:86:3a:22:4e:d0:1f:c3:56:d2:60:bd:
3a:0f:e8:2f:4b:54:02:a8:13:06:8f:c7:41:a8:6b:
e8:23:c2:b4:38:96:14:9a:42:56:04:0e:8c:8c:b2:
96:b5:1a:08:d1:b8:ce:c8:e3:56:59:68:c3:1d:d7:
07:66:56:1a:00:dd:e7:7e:00:cd:0c:4b:09:32:7b:
c6:fe:25:56:4e:93:a9:19:df:6a:f6:d9:1f:05:a6:
1b:65:54:c4:50:c5:98:d0:c1:3a:ae:dc:9c:ce:bd:
dc:fb:e8:b1:e9:32:2d:ea:16:d3:15:da:a6:a9:68:
0e:54:16:71:1e:39:cd:81:cc:37:1c:c0:e0:9f:01:
82:62:9e:09:f0:11:aa:56:eb:b0:e5:e4:d4:dd:1a:
b2:df:b7
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
D8:69:81:B4:FD:E9:45:1F:D9:FD:A6:C4:31:9C:84:5C:3C:B2:A5:6A
X509v3 Authority Key Identifier:
D8:69:81:B4:FD:E9:45:1F:D9:FD:A6:C4:31:9C:84:5C:3C:B2:A5:6A
X509v3 Basic Constraints: critical
CA:TRUE
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
56:68:81:05:ae:8c:45:59:6b:5d:14:0f:13:35:47:c2:41:c6:
0b:73:90:50:e7:d9:2a:a4:c5:9b:fd:86:dd:54:c7:80:47:e0:
45:29:16:07:91:26:83:af:57:df:a3:e2:83:06:64:57:cf:91:
aa:2c:cd:bc:97:86:7c:07:47:09:70:21:b0:4e:5c:78:d2:ec:
62:4d:40:8e:72:32:30:fe:04:0a:40:7f:9e:9b:5b:f8:d9:f9:
29:3b:c4:40:13:43:22:c3:96:51:3d:7b:d6:17:02:c4:d0:f0:
eb:16:49:d2:68:9b:82:9a:ef:1d:d3:54:a1:f3:aa:dc:92:ce:
56:3c:48:96:84:9a:76:99:dd:36:66:18:d1:fc:6b:3c:ed:f6:
29:a5:66:e4:5b:25:07:40:23:6f:11:40:28:40:30:b4:0c:f3:
43:57:1c:94:e7:79:5e:4c:69:ea:3e:7d:08:f2:07:85:2f:85:
a4:43:80:da:de:21:aa:cf:2e:eb:9a:56:c2:a7:3c:f7:0f:3a:
26:5f:ce:a7:80:78:91:1a:10:6c:18:39:1a:d8:5a:b4:04:46:
a3:6f:72:f3:96:ed:b0:21:fc:9a:0e:7d:24:cf:76:0b:71:de:
55:dc:52:18:2e:96:ab:1e:4d:d7:5d:6d:e0:a4:be:61:e0:6c:
21:23:ce:1e:d2:a8:50:d1:75:4b:8b:de:03:6c:e1:f0:04:f4:
ae:f3:f6:c0:39:83:b1:76:ab:d9:20:60:33:b4:6f:f2:af:28:
28:7d:79:69:67:a2:d1:07:77:ae:d5:31:ea:02:0c:5d:7c:de:
fc:b4:00:b7:98:c5:d1:9a:9a:dd:f0:ba:09:4b:51:7e:6f:2e:
1c:19:ef:42:33:1d:31:e7:43:d7:2d:41:34:3a:76:88:5c:83:
02:b8:c2:bd:0d:8e:11:23:0b:b3:80:1c:c4:5f:78:5e:45:40:
7d:35:0d:fb:34:17:b7:38:80:9e:8d:1e:32:e6:4e:67:1e:79:
a6:ef:cb:f2:c9:06:50:ca:ac:35:20:df:89:04:6d:9f:5b:fa:
82:68:06:a9:5d:ff:da:73:cb:6d:8a:98:c1:a1:8f:e3:01:d7:
27:c1:c9:99:c0:c2:39:3d:a2:87:2b:80:19:dc:8f:eb:39:02:
dc:96:cb:4d:41:19:9c:26:5b:bd:96:a2:d0:9d:2c:79:d6:57:
e1:48:27:96:9d:ee:11:54:16:31:c3:d3:c1:a7:be:a5:71:72:
22:20:62:e7:26:25:7a:e2:d7:32:22:ae:19:de:b6:08:12:1f:
ae:9e:0f:17:99:ab:15:af:c4:28:da:f6:b7:ce:a2:da:55:09:
f7:5c:06:6b:a0:ca:68:07

View File

@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDSbjhB8IK4urGY
wloF+YMrc51co3d40mIH99wmRO0yKett5cmCzQZfJLYckXcsTDmz3JBCVD5VroHn
5M5ag91P+k5MmR3qLz/rWmSpZmXYI+YCCWafnSQBvgwWQmXPT8kmD1oU/DwUEhMp
/6/YZV3cVlXdOTsAPMl45poGx8RoCDZD9cXBq8MOt8A6FAvSDOsm6JJTDLA+3WPp
HeKZjoFrZuyzRvKN11od1VoqBckvakmcpejCsH9DyYM3Y1waBCsZUNT6RQ/PdGrt
iRSDRUTODU+SqBbWkYydiksyRRBcEqVZuxW52YQco/cQ16yxnOsH+Ns3xKQ2/ltk
g0rHtjMJHrXb0VfWulVDuTx4G3fYEb7yHaCreZi3jN/cZ7WKLZK2cevKML9dcL/n
SWE18cQSVP3o9qhiF3N0YzkCjz40nGIFGC8Tq5NCMaqQiDip2wcu3YbgUulX6J5J
tJtJM29Hd5j6UkN24KcFuomGOiJO0B/DVtJgvToP6C9LVAKoEwaPx0Goa+gjwrQ4
lhSaQlYEDoyMspa1GgjRuM7I41ZZaMMd1wdmVhoA3ed+AM0MSwkye8b+JVZOk6kZ
32r22R8FphtlVMRQxZjQwTqu3JzOvdz76LHpMi3qFtMV2qapaA5UFnEeOc2BzDcc
wOCfAYJingnwEapW67Dl5NTdGrLftwIDAQABAoICABf5DY4EN+g9VfaODFJ07VVv
FkTTrKHbmeZy0tDwoPMfj8jVLlf+l9S7/8aREzoSia+swinZo2urIJ/fUwZAfTSG
KBMVjdu8O/R0jQDi1QRte9/MhrVKt4DpT+2Il++pFRncaDSkKGCtpHhFlENmB5jj
+bk6XWHhYEnWlO05J0N7eASAWeH+pDn82LiPyGmgJiP9x+RlOX5Cm4YXF6sgbyxi
Aoz0BAsBDIJXPYPfD99Hz7tkXU2HbPWMiKyFNHIUT9Knq55tbWfYHpxmtasKIlS1
HdUaiCuJU7MuP53U/Lr4jCovpEHS1CMCfPxIDc5YOaBkC0QMXMbqbaqtmGstyHId
sAxPI6ybvV6gaR8fRwVqtDvzt5u9qCi2UcVJiWluqwW9rM2A5fgQohME3HfH1gAd
e8lSypehkU44K0zR25DpsBi18hVRObGw/UaRIm44EzyFyYvCdzEVtvqzP9WV5nlg
6ip1d1EgcbGjd692dZ4VyfN1A9M7yoxTer0cL2CwaMSs23FKmbacyLYv80RM8qtX
4s6zVPN+nzeiwhI9WZ3f0mqMvs9Bh8oAT6p4Wj1Xswp3aqjTOR+kWLKXYtiHgZx8
bDyMy8lAFfDUSfD0Ca0gYDOv3Mi6i1H+WYeWHivs46A6eyzR+f8xRnAaLwgb/Nik
0iDcBtoSNCjBR+bXRpRhAoIBAQD4/htSRvdPZTRtzFTqQB7I66IqcuGRveLepbmY
SZHXIAmarS+VQ0n+hCASKZyw23zu8J8986F3J/Sr8KyESnpv22OPmBTxj4v/pw57
3hSpeflXKNYTyL2+f9o1cTHWGe6z04CNN1PbCkREze2C9j++TxapOxR4ZBYrMzfw
hhL4OvRWXmNoWxu0/yXTRMabbfaYkPE1aRPfPvGFEHbEe61vL7s1kFFFAxoSrovv
riT/g+dCDk+W6ZE0d87uUel0w5FcRj4w3tKmMIvLnQA+3MmDrcpW7Fp3PKzhTN6Q
AF+Pae9i3p8WjboOQ4ZHz+LWdDA9s19oUfdL3cZFTK8VIvmXAoIBAQDYWknktpne
EPJPy6ghXbDqi53O5+HxpEnsZzz6hUr2nVC/c/BDardPkzIq/P1ndKy1lhkZM31D
ChcjbSClLX+9Czhx8C+vXiBWy2Bouc+zPHC46Ua8Z+5T4SYMuKY6nV7duF1lx7e1
acFSqvyEaWMc2slpoNJL9rvUjLvZJXjr6G9O2OAOm87ZjMNTxwMJTvDfy9L2UvJj
CRI5NI039rHM3ZmxFRwnGFikzAgP35nkVEYA9AsTPEROwFDdcoBOwbZ5esg1ABfF
ixYHRsPeqg2mH4iFiClnVFAhVtrhXu2L68Vw/+qepAy7SLTNXRKtGZfRQCs4h8jn
W9ZCo+6Gks7hAoIBAQDcJghQGfDmIQxXHDfkGidd7IEoWQS6EJM72nmbfUjWVTxI
p2GP7rvIrleQ13v0H0x6EwQpCXU03n4FXDmciiFxLx/7QTMbVZkpxDIZMQVBx1e/
SZrmSTIC8hYj9F5k9+7GznU15rpcy9oKn6ylg0Ze5JybqmHyBERZk+Kc5l51XeLV
ToVEKnH3+TQfdQrJOFO1F0o9uBda5tMynJj2Jof069XxiRViGFkANZYCqA2MYbqh
+/dA7mh1ZIzwyDnLBHNMi8rG+Ox1Bi1ELR+fdSUzKQDjE/z0ug/88DNETSAwtDB1
UXKFxW/A1tEuQ09D390bYLI1kWs+h+qbMS8IWDEnAoIBAClbmSSPg3pf4vI+DDXU
oy0y40faK+b1cOwwEAgT0vCxwe3XS+aXT9N2X/C3y/kq5JkRyFp47UkTdLjg84yf
1ftdWbzuHS943tW4qwVZ/8pTk3jFnzAE7ho6v/tOkPhDfQ8FX1VFiGi1fq8+4Gav
frLVYAtBIvJCiEVpYb9w2ly+YgjAjJQ+VJxhvDUXpgzxejpNzFYqJQupgEJPOW+p
SPPQqMChOHCAxvE5z5C5PcHYGkm0XSmgK66iNNMgQEbN4QP35K29Bs5MeDmL3YWD
HHjVLlPYY5HNHERDRjQu4VoOCABB66fH1Gc4ztczI47ThaIKkjiMPGt9sseqbr5q
8gECggEAdwbfVu9UmvLttfDFRZTQYjEmG9xEQtFK+fMEdIHMp3clhRsvbHeeyUqA
s5RD2/la2/yzJnnxozZve5hVNZcK4m8Rx7Xe8qcHmV7PXiiEBJi+5ZVQ+Vub3RO/
/F7HJYHYf1KtZH8S6eXBRq4dhOWpjhCqnNJjYnPJEB/F0YjDNvrnV8maomiHwxZN
oUrSdPDltWMbNWxJXyL9YQNB6u8HBcPeYI/oxA3Ey/Mj/zot71jaJIGIpnzE9yw/
2heZ3rIdlwyEu+A5u0xLaFMbkDn9kuWUTRm/wKXVK2iYkzChwOH7KWnoff5KKR3p
qsK/+x4W4uA/Zr6JxO5sMmqI2Ubyqg==
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,8 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIBCjCBkgIBADATMREwDwYDVQQDDAhNb2NrIERTQzB2MBAGByqGSM49AgEGBSuB
BAAiA2IABJcHkktcOEim49CJ9XJgybYzwA76+dAO234h8RiXdoMG+fA1RCOiaWTw
fZNPZ+4WVZL69+qKfGoREW70CibyCElJugI91fAt+D8pGPxNOMzmst5cNYLDXOM8
UZ8/g+frOqAAMAoGCCqGSM49BAMCA2cAMGQCMFOGji5+Q5TfiHzCViOSpCtsgDvV
+ecUv6MGiFr1pfHVXbHgoAE2ixS+ed/LXX3ZpwIwHJ2qRDaWxMhFqMBgjrSIWbv7
vR/p/3jpKAQAmLuG5foVhsZN2Wi7Fk8pei4dS3ol
-----END CERTIFICATE REQUEST-----

View File

@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDUzCCATagAwIBAgIUDYcZscGWiuUrymtf8McZV1HPuOkwEgYJKoZIhvcNAQEK
MAWiAwIBIDAUMRIwEAYDVQQDDAlNb2NrIENTQ0EwHhcNMjUwMTA1MTIxMjEwWhcN
MjYwMTA1MTIxMjEwWjATMREwDwYDVQQDDAhNb2NrIERTQzB2MBAGByqGSM49AgEG
BSuBBAAiA2IABJcHkktcOEim49CJ9XJgybYzwA76+dAO234h8RiXdoMG+fA1RCOi
aWTwfZNPZ+4WVZL69+qKfGoREW70CibyCElJugI91fAt+D8pGPxNOMzmst5cNYLD
XOM8UZ8/g+frOqNCMEAwHQYDVR0OBBYEFNSFoVltdKnm+WoWGiEGCqIhCP15MB8G
A1UdIwQYMBaAFNhpgbT96UUf2f2mxDGchFw8sqVqMBIGCSqGSIb3DQEBCjAFogMC
ASADggIBAECM63yXNqLrOUooEdDnRWX0tno8+GJUZZa/BFm4ZfOTCtw3cH5aq5+5
XQAoPFz7G0bMyN3/3XvxZ2L4l+lMk2BjzIIiWvr3ssnlZfjIYwSuYdVy1XAcuriB
cmu8pN0VZGkp6IXwIciVNBj9SN9W7rsacqmqCx6e6WYMi85A8DslieSobpXrihFP
feip0HpFE1tcg4DYFXWKit4EuGQHuhax1payYsigXjeUseaun/PjqfXu1LVIrb/T
6CvcMZ7nttUBbr15nCchrkUWwD0O0l5xqI6iuMtlS3Sph/tMQo8obuVvgyBgF+PZ
YtK2FuNC8LRmu+lf6J3TVCArw5n6Xs4bVq9AFd+hq+zsC5+zRHVctQKTvYHDZWZT
ykPUBoBHoKoKIw9PibdBwXruVDgkYVN8uOi9gNtgxAT8i2gElRyZA5IGpA6Ov6yG
2hhMuXYz2y3yTCGic9n2kpgTKiEN/SFFkwKgNYFgxx68E/LQTRHET0U8jd81MMk5
jfkd2q0rMmuUnR9UJaML6KR+uDimmJ5sFgB554bi4celuHweK5Jma1AaSGgywhqm
iseo6+Z0RI3/Qg6Iq99YaUZdJv7Ei/xUwyO/ALM/DnZdApgFO+cpEODdt5U3sukA
/OEle+F0PODMfa2140mDEo0r5Jn+AZjR5VswzDv25EwsyyhrPkMe
-----END CERTIFICATE-----

View File

@@ -0,0 +1,68 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
0d:87:19:b1:c1:96:8a:e5:2b:ca:6b:5f:f0:c7:19:57:51:cf:b8:e9
Signature Algorithm: rsassaPss
Hash Algorithm: sha1 (default)
Mask Algorithm: mgf1 with sha1 (default)
Salt Length: 0x20
Trailer Field: 0x01 (default)
Issuer: CN=Mock CSCA
Validity
Not Before: Jan 5 12:12:10 2025 GMT
Not After : Jan 5 12:12:10 2026 GMT
Subject: CN=Mock DSC
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (384 bit)
pub:
04:97:07:92:4b:5c:38:48:a6:e3:d0:89:f5:72:60:
c9:b6:33:c0:0e:fa:f9:d0:0e:db:7e:21:f1:18:97:
76:83:06:f9:f0:35:44:23:a2:69:64:f0:7d:93:4f:
67:ee:16:55:92:fa:f7:ea:8a:7c:6a:11:11:6e:f4:
0a:26:f2:08:49:49:ba:02:3d:d5:f0:2d:f8:3f:29:
18:fc:4d:38:cc:e6:b2:de:5c:35:82:c3:5c:e3:3c:
51:9f:3f:83:e7:eb:3a
ASN1 OID: secp384r1
NIST CURVE: P-384
X509v3 extensions:
X509v3 Subject Key Identifier:
D4:85:A1:59:6D:74:A9:E6:F9:6A:16:1A:21:06:0A:A2:21:08:FD:79
X509v3 Authority Key Identifier:
D8:69:81:B4:FD:E9:45:1F:D9:FD:A6:C4:31:9C:84:5C:3C:B2:A5:6A
Signature Algorithm: rsassaPss
Signature Value:
Hash Algorithm: sha1 (default)
Mask Algorithm: mgf1 with sha1 (default)
Salt Length: 0x20
Trailer Field: 0x01 (default)
40:8c:eb:7c:97:36:a2:eb:39:4a:28:11:d0:e7:45:65:f4:b6:
7a:3c:f8:62:54:65:96:bf:04:59:b8:65:f3:93:0a:dc:37:70:
7e:5a:ab:9f:b9:5d:00:28:3c:5c:fb:1b:46:cc:c8:dd:ff:dd:
7b:f1:67:62:f8:97:e9:4c:93:60:63:cc:82:22:5a:fa:f7:b2:
c9:e5:65:f8:c8:63:04:ae:61:d5:72:d5:70:1c:ba:b8:81:72:
6b:bc:a4:dd:15:64:69:29:e8:85:f0:21:c8:95:34:18:fd:48:
df:56:ee:bb:1a:72:a9:aa:0b:1e:9e:e9:66:0c:8b:ce:40:f0:
3b:25:89:e4:a8:6e:95:eb:8a:11:4f:7d:e8:a9:d0:7a:45:13:
5b:5c:83:80:d8:15:75:8a:8a:de:04:b8:64:07:ba:16:b1:d6:
96:b2:62:c8:a0:5e:37:94:b1:e6:ae:9f:f3:e3:a9:f5:ee:d4:
b5:48:ad:bf:d3:e8:2b:dc:31:9e:e7:b6:d5:01:6e:bd:79:9c:
27:21:ae:45:16:c0:3d:0e:d2:5e:71:a8:8e:a2:b8:cb:65:4b:
74:a9:87:fb:4c:42:8f:28:6e:e5:6f:83:20:60:17:e3:d9:62:
d2:b6:16:e3:42:f0:b4:66:bb:e9:5f:e8:9d:d3:54:20:2b:c3:
99:fa:5e:ce:1b:56:af:40:15:df:a1:ab:ec:ec:0b:9f:b3:44:
75:5c:b5:02:93:bd:81:c3:65:66:53:ca:43:d4:06:80:47:a0:
aa:0a:23:0f:4f:89:b7:41:c1:7a:ee:54:38:24:61:53:7c:b8:
e8:bd:80:db:60:c4:04:fc:8b:68:04:95:1c:99:03:92:06:a4:
0e:8e:bf:ac:86:da:18:4c:b9:76:33:db:2d:f2:4c:21:a2:73:
d9:f6:92:98:13:2a:21:0d:fd:21:45:93:02:a0:35:81:60:c7:
1e:bc:13:f2:d0:4d:11:c4:4f:45:3c:8d:df:35:30:c9:39:8d:
f9:1d:da:ad:2b:32:6b:94:9d:1f:54:25:a3:0b:e8:a4:7e:b8:
38:a6:98:9e:6c:16:00:79:e7:86:e2:e1:c7:a5:b8:7c:1e:2b:
92:66:6b:50:1a:48:68:32:c2:1a:a6:8a:c7:a8:eb:e6:74:44:
8d:ff:42:0e:88:ab:df:58:69:46:5d:26:fe:c4:8b:fc:54:c3:
23:bf:00:b3:3f:0e:76:5d:02:98:05:3b:e7:29:10:e0:dd:b7:
95:37:b2:e9:00:fc:e1:25:7b:e1:74:3c:e0:cc:7d:ad:b5:e3:
49:83:12:8d:2b:e4:99:fe:01:98:d1:e5:5b:30:cc:3b:f6:e4:
4c:2c:cb:28:6b:3e:43:1e

View File

@@ -0,0 +1,6 @@
-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDDabeMgcheTsizT6aH0CiXxb1gvSHQNjbcqJCooAljzzEyLdAeCOhoA
ureFOIfii2ugBwYFK4EEACKhZANiAASXB5JLXDhIpuPQifVyYMm2M8AO+vnQDtt+
IfEYl3aDBvnwNUQjomlk8H2TT2fuFlWS+vfqinxqERFu9Aom8ghJSboCPdXwLfg/
KRj8TTjM5rLeXDWCw1zjPFGfP4Pn6zo=
-----END EC PRIVATE KEY-----

View File

@@ -0,0 +1,164 @@
import { saltLengths } from "../constants/constants";
import { hashAlgos } from "../constants/constants";
import { CertificateData, PublicKeyDetailsECDSA, PublicKeyDetailsRSA } from "./certificate_parsing/dataStructure";
import { initElliptic } from "./certificate_parsing/elliptic";
import * as asn1js from "asn1js";
import * as forge from "node-forge";
import { getCurveForElliptic } from "./certificate_parsing/curves";
import { Certificate } from "pkijs";
import { hash } from "./utils";
export function brutforceSignatureAlgorithmDsc(dsc: CertificateData, csca: CertificateData) {
if (csca.signatureAlgorithm === 'ecdsa') {
const hashAlgorithm = brutforceHashAlgorithmDsc(dsc, csca, 'ecdsa');
return {
signatureAlgorithm: 'ecdsa',
hashAlgorithm: hashAlgorithm,
saltLength: 0,
};
}
else if (csca.signatureAlgorithm === 'rsa') {
const hashAlgorithm = brutforceHashAlgorithmDsc(dsc, csca, 'rsa');
if (hashAlgorithm) {
return {
signatureAlgorithm: 'rsa',
hashAlgorithm: hashAlgorithm,
saltLength: 0,
};
}
}
//it's important to not put 'else if' statement here, because a rsapss signature can use rsa key certificate.
for (const saltLength of saltLengths) {
const hashAlgorithm = brutforceHashAlgorithmDsc(dsc, csca, 'rsapss', saltLength);
if (hashAlgorithm) {
return {
signatureAlgorithm: 'rsapss',
hashAlgorithm: hashAlgorithm,
saltLength: saltLength,
};
}
}
}
function brutforceHashAlgorithmDsc(dsc: CertificateData, csca: CertificateData, signatureAlgorithm: string, saltLength?: number): any {
for (const hashFunction of hashAlgos) {
// console.log(`\nTrying hash function: ${hashFunction}`);
if (verifySignature(dsc, csca, signatureAlgorithm, hashFunction, saltLength)) {
// console.log(`✓ Success with hash function: ${hashFunction}`);
return hashFunction;
}
// console.log(`✗ Failed with hash function: ${hashFunction}`);
}
return false;
}
function verifySignature(dsc: CertificateData, csca: CertificateData, signatureAlgorithm: string, hashAlgorithm: string, saltLength: number = 0): boolean {
switch (signatureAlgorithm) {
case 'ecdsa':
return verifyECDSA(dsc, csca, hashAlgorithm);
case 'rsa':
return verifyRSA(dsc, csca, hashAlgorithm);
case 'rsapss':
return verifyRSAPSS(dsc, csca, hashAlgorithm, saltLength);
}
}
function verifyECDSA(dsc: CertificateData, csca: CertificateData, hashAlgorithm: string): boolean {
const elliptic = initElliptic();
const certBuffer_csca = Buffer.from(
csca.rawPem.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ''),
'base64'
);
const asn1Data_csca = asn1js.fromBER(certBuffer_csca);
const cert_csca = new Certificate({ schema: asn1Data_csca.result });
const publicKeyInfo_csca = cert_csca.subjectPublicKeyInfo;
const publicKeyBuffer_csca = publicKeyInfo_csca.subjectPublicKey.valueBlock.valueHexView;
const curveForElliptic_csca = getCurveForElliptic((csca.publicKeyDetails as PublicKeyDetailsECDSA).curve);
const ec_csca = new elliptic.ec(curveForElliptic_csca);
const key_csca = ec_csca.keyFromPublic(publicKeyBuffer_csca);
const tbsHash = getTBSHash(dsc.rawPem, hashAlgorithm, 'hex');
const certBuffer_dsc = Buffer.from(
dsc.rawPem.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ''),
'base64'
);
const asn1Data_dsc = asn1js.fromBER(certBuffer_dsc);
const cert_dsc = new Certificate({ schema: asn1Data_dsc.result });
const signatureValue = cert_dsc.signatureValue.valueBlock.valueHexView;
const signature_crypto = Buffer.from(signatureValue).toString('hex');
return key_csca.verify(tbsHash, signature_crypto);
}
function verifyRSA(dsc: CertificateData, csca: CertificateData, hashAlgorithm: string): boolean {
try {
const dscCert = forge.pki.certificateFromPem(dsc.rawPem);
const cscaCert = forge.pki.certificateFromPem(csca.rawPem);
const tbsHash = getTBSHash(dsc.rawPem, hashAlgorithm);
if (!tbsHash) {
return false;
}
const publicKey = cscaCert.publicKey as forge.pki.rsa.PublicKey;
const signature = dscCert.signature;
try {
const verified = publicKey.verify(tbsHash, signature);
return verified;
} catch (verifyError) {
return false;
}
} catch (error) {
return false;
}
}
function verifyRSAPSS(dsc: CertificateData, csca: CertificateData, hashAlgorithm: string, saltLength: number): boolean {
try {
const dscCert = forge.pki.certificateFromPem(dsc.rawPem);
const cscaCert = forge.pki.certificateFromPem(csca.rawPem);
const tbsHash = getTBSHash(dsc.rawPem, hashAlgorithm);
if (!tbsHash) {
return false;
}
const publicKey = cscaCert.publicKey as forge.pki.rsa.PublicKey;
const signature = dscCert.signature;
if (saltLength === 0) {
throw new Error('Salt length is required for RSA-PSS');
}
try {
const pss = forge.pss.create({
md: forge.md[hashAlgorithm].create(),
mgf: forge.mgf.mgf1.create(forge.md[hashAlgorithm].create()),
saltLength: saltLength,
});
return publicKey.verify(tbsHash, signature, pss);
} catch (verifyError) {
return false;
}
} catch (error) {
return false;
}
}
export function getTBSHash(
pem: string,
hashFunction: string,
format: 'hex' | 'data' = 'data',
): string {
const certBuffer = Buffer.from(
pem.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ''),
'base64'
);
const asn1Data_cert = asn1js.fromBER(certBuffer);
const cert = new Certificate({ schema: asn1Data_cert.result });
const tbsAsn1 = cert.encodeTBS();
const tbsDer = tbsAsn1.toBER(false);
const tbsBytes = Buffer.from(tbsDer);
const tbsBytesArray = Array.from(tbsBytes);
const msgHash = hash(hashFunction, tbsBytesArray, format === 'hex' ? 'hex' : 'binary');
return msgHash as string;
}

View File

@@ -0,0 +1,127 @@
import { PassportData } from './types';
import { parseCertificateSimple } from './certificate_parsing/parseCertificateSimple';
import {
PublicKeyDetailsECDSA,
} from './certificate_parsing/dataStructure';
import forge, { md } from 'node-forge';
import * as asn1js from 'asn1js';
import { initElliptic } from './certificate_parsing/elliptic';
import { getCurveForElliptic } from './certificate_parsing/curves';
import { Certificate } from 'pkijs';
import { hashAlgos, saltLengths } from '../constants/constants';
import { hash } from './utils';
export function brutforceSignatureAlgorithm(passportData: PassportData) {
const parsedDsc = parseCertificateSimple(passportData.dsc);
if (parsedDsc.signatureAlgorithm === 'ecdsa') {
const hashAlgorithm = brutforceHashAlgorithm(passportData, 'ecdsa');
return {
signatureAlgorithm: 'ecdsa',
hashAlgorithm: hashAlgorithm,
saltLength: 0,
};
}
else if (parsedDsc.signatureAlgorithm === 'rsa') {
const hashAlgorithm = brutforceHashAlgorithm(passportData, 'rsa');
if (hashAlgorithm) {
return {
signatureAlgorithm: 'rsa',
hashAlgorithm: hashAlgorithm,
saltLength: 0,
};
}
}
// it's important to not put 'else if' statement here, because a rsapss signature can use rsa key certificate.
for (const saltLength of saltLengths) {
const hashAlgorithm = brutforceHashAlgorithm(passportData, 'rsapss', saltLength);
if (hashAlgorithm) {
return {
signatureAlgorithm: 'rsapss',
hashAlgorithm: hashAlgorithm,
saltLength: saltLength,
};
}
}
}
function brutforceHashAlgorithm(passportData: PassportData, signatureAlgorithm: string, saltLength?: number): any {
for (const hashFunction of hashAlgos) {
if (verifySignature(passportData, signatureAlgorithm, hashFunction, saltLength)) {
return hashFunction;
}
}
return false;
}
export function verifySignature(passportData: PassportData, signatureAlgorithm: string, hashAlgorithm: string, saltLength: number = 0): boolean {
switch (signatureAlgorithm) {
case 'ecdsa':
return verifyECDSA(passportData, hashAlgorithm);
case 'rsa':
return verifyRSA(passportData, hashAlgorithm);
case 'rsapss':
return verifyRSAPSS(passportData, hashAlgorithm, saltLength);
}
}
function verifyECDSA(passportData: PassportData, hashAlgorithm: string) {
const elliptic = initElliptic();
const { dsc, signedAttr, encryptedDigest } = passportData;
const { publicKeyDetails } = parseCertificateSimple(dsc);
const certBuffer = Buffer.from(
dsc.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ''),
'base64'
);
const asn1Data = asn1js.fromBER(certBuffer);
const cert = new Certificate({ schema: asn1Data.result });
const publicKeyInfo = cert.subjectPublicKeyInfo;
const publicKeyBuffer = publicKeyInfo.subjectPublicKey.valueBlock.valueHexView;
const curveForElliptic = getCurveForElliptic((publicKeyDetails as PublicKeyDetailsECDSA).curve);
const ec = new elliptic.ec(curveForElliptic);
const key = ec.keyFromPublic(publicKeyBuffer);
const msgHash = hash(hashAlgorithm, signedAttr, 'hex');
const signature_crypto = Buffer.from(encryptedDigest).toString('hex');
return key.verify(msgHash, signature_crypto);
}
function verifyRSA(passportData: PassportData, hashAlgorithm: string) {
const { dsc, signedAttr, encryptedDigest } = passportData;
const cert = forge.pki.certificateFromPem(dsc);
const publicKey = cert.publicKey as forge.pki.rsa.PublicKey;
const msgHash = hash(hashAlgorithm, signedAttr, 'binary');
const signature = Buffer.from(encryptedDigest).toString('binary');
try {
return publicKey.verify(msgHash as string, signature);
} catch (error) {
return false;
}
}
function verifyRSAPSS(passportData: PassportData, hashAlgorithm: string, saltLength: number) {
const { dsc, signedAttr, encryptedDigest } = passportData;
const cert = forge.pki.certificateFromPem(dsc);
const publicKey = cert.publicKey as forge.pki.rsa.PublicKey;
const msgHash = hash(hashAlgorithm, signedAttr, 'binary');
const signature = Buffer.from(encryptedDigest).toString('binary');
if (saltLength === 0) {
throw new Error('Salt length is required for RSA-PSS');
}
try {
const pss = forge.pss.create({
md: forge.md[hashAlgorithm].create(),
mgf: forge.mgf.mgf1.create(forge.md[hashAlgorithm].create()),
saltLength: saltLength,
});
return publicKey.verify(msgHash as string, signature, pss);
} catch (error) {
return false;
}
}

View File

@@ -1,141 +1,141 @@
export interface StandardCurve {
name: string;
p: string;
a: string;
b: string;
G: string;
n: string;
h: string;
name: string;
p: string;
a: string;
b: string;
G: string;
n: string;
h: string;
}
export const standardCurves: StandardCurve[] = [
{
name: "secp256r1",
p: "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
a: "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
b: "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
G: "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
n: "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
h: "01"
},
{
name: "secp384r1",
p: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
a: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
b: "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
G: "04AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
n: "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
h: "01"
},
{
name: "secp521r1",
p: "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
a: "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
b: "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
G: "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
n: "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
h: "01"
},
{
name: "brainpoolP224r1",
p: "d7c134aa264366862a18302575d1d787b09f075797da89f57ec8c0ff",
a: "68a5e62ca9ce6c1c299803a6c1530b514e182ad8b0042a59cad29f43",
b: "2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b",
G: "040d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd",
n: "d7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f",
h: "01"
},
{
name: "brainpoolP256r1",
p: "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
a: "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
b: "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
G: "048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
n: "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
h: "01"
},
{
name: "brainpoolP384r1",
p: "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
a: "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
b: "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
G: "041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
n: "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
h: "01"
},
{
name: "brainpoolP512r1",
p: "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
a: "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
b: "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
G: "0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
n: "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
h: "01"
}
{
name: 'secp256r1',
p: 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF',
a: 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC',
b: '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B',
G: '046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5',
n: 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551',
h: '01',
},
{
name: 'secp384r1',
p: 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF',
a: 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC',
b: 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF',
G: '04AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F',
n: 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973',
h: '01',
},
{
name: 'secp521r1',
p: '01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',
a: '01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC',
b: '0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00',
G: '0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650',
n: '01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409',
h: '01',
},
{
name: 'brainpoolP224r1',
p: 'd7c134aa264366862a18302575d1d787b09f075797da89f57ec8c0ff',
a: '68a5e62ca9ce6c1c299803a6c1530b514e182ad8b0042a59cad29f43',
b: '2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b',
G: '040d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd',
n: 'd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f',
h: '01',
},
{
name: 'brainpoolP256r1',
p: 'A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377',
a: '7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9',
b: '26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6',
G: '048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997',
n: 'A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7',
h: '01',
},
{
name: 'brainpoolP384r1',
p: '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53',
a: '7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826',
b: '04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11',
G: '041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315',
n: '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565',
h: '01',
},
{
name: 'brainpoolP512r1',
p: 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3',
a: '7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA',
b: '3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723',
G: '0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892',
n: 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069',
h: '01',
},
];
export function normalizeHex(hex: string): string {
return hex.toLowerCase().replace(/^0x/, '').replace(/^00/, '');
return hex.toLowerCase().replace(/^0x/, '').replace(/^00/, '');
}
export function identifyCurve(params: any): string {
const normalizedParams = {
p: normalizeHex(params.p),
a: normalizeHex(params.a),
b: normalizeHex(params.b),
G: normalizeHex(params.G),
n: normalizeHex(params.n),
h: normalizeHex(params.h)
};
const normalizedParams = {
p: normalizeHex(params.p),
a: normalizeHex(params.a),
b: normalizeHex(params.b),
G: normalizeHex(params.G),
n: normalizeHex(params.n),
h: normalizeHex(params.h),
};
for (const curve of standardCurves) {
if (
normalizedParams.p === normalizeHex(curve.p) &&
normalizedParams.a === normalizeHex(curve.a) &&
normalizedParams.b === normalizeHex(curve.b) &&
normalizedParams.G === normalizeHex(curve.G) &&
normalizedParams.n === normalizeHex(curve.n) &&
normalizedParams.h === normalizeHex(curve.h)
) {
return curve.name;
}
for (const curve of standardCurves) {
if (
normalizedParams.p === normalizeHex(curve.p) &&
normalizedParams.a === normalizeHex(curve.a) &&
normalizedParams.b === normalizeHex(curve.b) &&
normalizedParams.G === normalizeHex(curve.G) &&
normalizedParams.n === normalizeHex(curve.n) &&
normalizedParams.h === normalizeHex(curve.h)
) {
return curve.name;
}
console.log("Unknown curve:", normalizedParams);
return "Unknown curve";
}
console.log('Unknown curve:', normalizedParams);
return 'Unknown curve';
}
export function getECDSACurveBits(curveName: string): string {
const curveBits: { [key: string]: number } = {
'secp224r1': 224,
'secp256r1': 256,
'secp384r1': 384,
'secp521r1': 521,
'brainpoolP224r1': 224,
'brainpoolP256r1': 256,
'brainpoolP384r1': 384,
'brainpoolP512r1': 512
};
if (curveName in curveBits) {
return curveBits[curveName].toString();
}
console.log('\x1b[31m%s\x1b[0m', `curve name ${curveName} not found in curveBits`);
return "unknown";
const curveBits: { [key: string]: number } = {
secp224r1: 224,
secp256r1: 256,
secp384r1: 384,
secp521r1: 521,
brainpoolP224r1: 224,
brainpoolP256r1: 256,
brainpoolP384r1: 384,
brainpoolP512r1: 512,
};
if (curveName in curveBits) {
return curveBits[curveName].toString();
}
console.log('\x1b[31m%s\x1b[0m', `curve name ${curveName} not found in curveBits`);
return 'unknown';
}
export function getCurveForElliptic(curveName: string): string {
const curves = {
secp224r1: 'p224',
secp256r1: 'p256',
secp384r1: 'p384',
secp521r1: 'p521',
brainpoolP224r1: 'brainpoolP224r1',
brainpoolP256r1: 'brainpoolP256r1',
brainpoolP384r1: 'brainpoolP384r1',
brainpoolP512r1: 'brainpoolP512r1',
};
const curves = {
secp224r1: 'p224',
secp256r1: 'p256',
secp384r1: 'p384',
secp521r1: 'p521',
brainpoolP224r1: 'brainpoolP224r1',
brainpoolP256r1: 'brainpoolP256r1',
brainpoolP384r1: 'brainpoolP384r1',
brainpoolP512r1: 'brainpoolP512r1',
};
if (!curves[curveName]) {
throw new Error('Invalid curve: ' + curveName);
}
if (!curves[curveName]) {
throw new Error('Invalid curve: ' + curveName);
}
return curves[curveName];
}
return curves[curveName];
}

View File

@@ -1,37 +1,41 @@
import { StandardCurve } from "./curves";
import { StandardCurve } from './curves';
export interface CertificateData {
id: string;
issuer: string;
validity: {
notBefore: string;
notAfter: string;
};
subjectKeyIdentifier: string;
authorityKeyIdentifier: string;
signatureAlgorithm: string;
hashAlgorithm: string;
publicKeyDetails: PublicKeyDetailsRSA | PublicKeyDetailsECDSA | PublicKeyDetailsRSAPSS | undefined;
rawPem: string;
rawTxt: string;
id: string;
issuer: string;
validity: {
notBefore: string;
notAfter: string;
};
subjectKeyIdentifier: string;
authorityKeyIdentifier: string;
signatureAlgorithm: string;
hashAlgorithm: string;
publicKeyDetails:
| PublicKeyDetailsRSA
| PublicKeyDetailsECDSA
| PublicKeyDetailsRSAPSS
| undefined;
rawPem: string;
rawTxt: string;
}
export interface PublicKeyDetailsRSA {
modulus: string;
exponent: string;
bits: string;
modulus: string;
exponent: string;
bits: string;
}
export interface PublicKeyDetailsRSAPSS extends PublicKeyDetailsRSA {
hashAlgorithm: string;
mgf: string;
saltLength: string;
hashAlgorithm: string;
mgf: string;
saltLength: string;
}
export interface PublicKeyDetailsECDSA {
x: string;
y: string;
curve: string;
params: StandardCurve;
bits: string;
}
x: string;
y: string;
curve: string;
params: StandardCurve;
bits: string;
}

View File

@@ -0,0 +1,85 @@
import elliptic from 'elliptic';
import hash from 'hash.js';
export function initElliptic(): typeof elliptic {
const curves = elliptic.curves;
const PresetCurve = elliptic.curves.PresetCurve;
function defineCurve(name: string, options: any) {
Object.defineProperty(curves, name, {
configurable: true,
enumerable: true,
get: function () {
var curve = new PresetCurve(options);
Object.defineProperty(curves, name, {
configurable: true,
enumerable: true,
value: curve,
});
return curve;
},
});
}
defineCurve('brainpoolP224r1', {
type: 'short',
prime: null,
p: 'd7c134aa 26436686 2a183025 75d1d787 b09f0757 97da89f5 7ec8c0ff',
a: '68a5e62c a9ce6c1c 299803a6 c1530b51 4e182ad8 b0042a59 cad29f43',
b: '2580f63c cfe44138 870713b1 a92369e3 3e2135d2 66dbb372 386c400b',
n: 'd7c134aa 26436686 2a183025 75d0fb98 d116bc4b 6ddebca3 a5a7939f',
hash: hash.sha1,
gRed: false,
g: [
'0d9029ad 2c7e5cf4 340823b2 a87dc68c 9e4ce317 4c1e6efd ee12c07d',
'58aa56f7 72c0726f 24c6b89e 4ecdac24 354b9e99 caa3f6d3 761402cd',
],
});
defineCurve('brainpoolP256r1', {
type: 'short',
prime: null,
p: 'a9fb57db a1eea9bc 3e660a90 9d838d72 6e3bf623 d5262028 2013481d 1f6e5377',
a: '7d5a0975 fc2c3057 eef67530 417affe7 fb8055c1 26dc5c6c e94a4b44 f330b5d9',
b: '26dc5c6c e94a4b44 f330b5d9 bbd77cbf 95841629 5cf7e1ce 6bccdc18 ff8c07b6',
n: 'a9fb57db a1eea9bc 3e660a90 9d838d71 8c397aa3 b561a6f7 901e0e82 974856a7',
hash: hash.sha256,
gRed: false,
g: [
'8bd2aeb9 cb7e57cb 2c4b482f fc81b7af b9de27e1 e3bd23c2 3a4453bd 9ace3262',
'547ef835 c3dac4fd 97f8461a 14611dc9 c2774513 2ded8e54 5c1d54c7 2f046997',
],
});
defineCurve('brainpoolP384r1', {
type: 'short',
prime: null,
p: '8cb91e82 a3386d28 0f5d6f7e 50e641df 152f7109 ed5456b4 12b1da19 7fb71123 acd3a729 901d1a71 87470013 3107ec53',
a: '7bc382c6 3d8c150c 3c72080a ce05afa0 c2bea28e 4fb22787 139165ef ba91f90f 8aa5814a 503ad4eb 04a8c7dd 22ce2826',
b: '04a8c7dd 22ce2826 8b39b554 16f0447c 2fb77de1 07dcd2a6 2e880ea5 3eeb62d5 7cb43902 95dbc994 3ab78696 fa504c11',
n: '8cb91e82 a3386d28 0f5d6f7e 50e641df 152f7109 ed5456b3 1f166e6c ac0425a7 cf3ab6af 6b7fc310 3b883202 e9046565',
hash: hash.sha384,
gRed: false,
g: [
'1d1c64f0 68cf45ff a2a63a81 b7c13f6b 8847a3e7 7ef14fe3 db7fcafe 0cbd10e8 e826e034 36d646aa ef87b2e2 47d4af1e',
'8abe1d75 20f9c2a4 5cb1eb8e 95cfd552 62b70b29 feec5864 e19c054f f9912928 0e464621 77918111 42820341 263c5315',
],
});
defineCurve('brainpoolP512r1', {
type: 'short',
prime: null,
p: 'aadd9db8 dbe9c48b 3fd4e6ae 33c9fc07 cb308db3 b3c9d20e d6639cca 70330871 7d4d9b00 9bc66842 aecda12a e6a380e6 2881ff2f 2d82c685 28aa6056 583a48f3',
a: '7830a331 8b603b89 e2327145 ac234cc5 94cbdd8d 3df91610 a83441ca ea9863bc 2ded5d5a a8253aa1 0a2ef1c9 8b9ac8b5 7f1117a7 2bf2c7b9 e7c1ac4d 77fc94ca',
b: '3df91610 a83441ca ea9863bc 2ded5d5a a8253aa1 0a2ef1c9 8b9ac8b5 7f1117a7 2bf2c7b9 e7c1ac4d 77fc94ca dc083e67 984050b7 5ebae5dd 2809bd63 8016f723',
n: 'aadd9db8 dbe9c48b 3fd4e6ae 33c9fc07 cb308db3 b3c9d20e d6639cca 70330870 553e5c41 4ca92619 41866119 7fac1047 1db1d381 085ddadd b5879682 9ca90069',
hash: hash.sha512,
gRed: false,
g: [
'81aee4bd d82ed964 5a21322e 9c4c6a93 85ed9f70 b5d916c1 b43b62ee f4d0098e ff3b1f78 e2d0d48d 50d1687b 93b97d5f 7c6d5047 406a5e68 8b352209 bcb9f822',
'7dde385d 566332ec c0eabfa9 cf7822fd f209f700 24a57b1a a000c55b 881f8111 b2dcde49 4a5f485e 5bca4bd8 8a2763ae d1ca2b2f a8f05406 78cd1e0f 3ad80892',
],
});
return elliptic;
}

View File

@@ -1,138 +1,138 @@
export const oidMap: { [key: string]: string } = {
"1.2.840.113549.3.7": "3des",
"2.16.840.1.101.3.4.1.2": "aes128",
"2.16.840.1.101.3.4.1.5": "aes128wrap",
"2.16.840.1.101.3.4.1.22": "aes192",
"2.16.840.1.101.3.4.1.25": "aes192wrap",
"2.16.840.1.101.3.4.1.42": "aes256",
"2.16.840.1.101.3.4.1.45": "aes256wrap",
"1.3.36.3.3.2.8.1.1.1": "brainpoolP160r1",
"1.3.36.3.3.2.8.1.1.2": "brainpoolP160t1",
"1.3.36.3.3.2.8.1.1.3": "brainpoolP192r1",
"1.3.36.3.3.2.8.1.1.4": "brainpoolP192t1",
"1.3.36.3.3.2.8.1.1.5": "brainpoolP224r1",
"1.3.36.3.3.2.8.1.1.6": "brainpoolP224t1",
"1.3.36.3.3.2.8.1.1.7": "brainpoolP256r1",
"1.3.36.3.3.2.8.1.1.8": "brainpoolP256t1",
"1.3.36.3.3.2.8.1.1.9": "brainpoolP320r1",
"1.3.36.3.3.2.8.1.1.10": "brainpoolP320t1",
"1.3.36.3.3.2.8.1.1.11": "brainpoolP384r1",
"1.3.36.3.3.2.8.1.1.12": "brainpoolP384t1",
"1.3.36.3.3.2.8.1.1.13": "brainpoolP512r1",
"1.3.36.3.3.2.8.1.1.14": "brainpoolP512t1",
"2.5.4.6": "C",
"1.2.840.113549.1.9.16.3.6": "CMS3DESwrap",
"1.2.840.113549.1.9.16.3.7": "CMSRC2wrap",
"2.5.4.3": "CN",
"1.3.6.1.5.5.7.2.1": "CPS",
"0.9.2342.19200300.100.1.25": "DC",
"1.3.14.3.2.7": "des",
"2.5.4.13": "Description",
"1.2.840.10046.2.1": "DH",
"2.5.4.46": "dnQualifier",
"1.2.840.10040.4.1": "DSA",
"1.3.14.3.2.27": "dsaSHA1",
"1.2.840.113549.1.9.1": "E",
"1.2.156.11235.1.1.2.1": "ec192wapi",
"1.2.840.10045.2.1": "ECC",
"1.3.133.16.840.63.0.2": "ECDH_STD_SHA1_KDF",
"1.3.132.1.11.1": "ECDH_STD_SHA256_KDF",
"1.3.132.1.11.2": "ECDH_STD_SHA384_KDF",
"1.2.840.10045.3.1.7": "ECDSA_P256",
"1.3.132.0.34": "ECDSA_P384",
"1.3.132.0.35": "ECDSA_P521",
"1.2.840.113549.1.9.16.3.5": "ESDH",
"2.5.4.42": "G",
"2.5.4.43": "I",
"2.5.4.7": "L",
"1.2.840.113549.2.2": "md2",
"1.2.840.113549.1.1.2": "md2RSA",
"1.2.840.113549.2.4": "md4",
"1.2.840.113549.1.1.3": "md4RSA",
"1.2.840.113549.2.5": "md5",
"1.2.840.113549.1.1.4": "md5RSA",
"1.2.840.113549.1.1.8": "mgf1",
"2.16.840.1.101.2.1.1.20": "mosaicKMandUpdSig",
"2.16.840.1.101.2.1.1.19": "mosaicUpdatedSig",
"1.2.840.10045.3.1.1": "nistP192",
"1.3.132.0.33": "nistP224",
"1.3.6.1.5.5.7.6.2": "NO_SIGN",
"2.5.4.10": "O",
"2.5.4.11": "OU",
"2.5.4.20": "Phone",
"2.5.4.18": "POBox",
"2.5.4.17": "PostalCode",
"1.2.840.113549.3.2": "rc2",
"1.2.840.113549.3.4": "rc4",
"1.2.840.113549.1.1.1": "RSA",
"1.2.840.113549.1.1.7": "RSAES_OAEP",
"1.2.840.113549.1.1.10": "RSASSA_PSS",
"2.5.4.8": "S",
"1.3.132.0.9": "secP160k1",
"1.3.132.0.8": "secP160r1",
"1.3.132.0.30": "secP160r2",
"1.3.132.0.31": "secP192k1",
"1.3.132.0.32": "secP224k1",
"1.3.132.0.10": "secP256k1",
"2.5.4.5": "SERIALNUMBER",
"1.3.14.3.2.26": "sha1",
"1.2.840.10040.4.3": "sha1DSA",
"1.2.840.10045.4.1": "sha1ECDSA",
"1.2.840.113549.1.1.5": "sha1RSA",
"2.16.840.1.101.3.4.2.1": "sha256",
"1.2.840.10045.4.3.2": "sha256ECDSA",
"1.2.840.113549.1.1.11": "sha256RSA",
"2.16.840.1.101.3.4.2.2": "sha384",
"1.2.840.10045.4.3.3": "sha384ECDSA",
"1.2.840.113549.1.1.12": "sha384RSA",
"2.16.840.1.101.3.4.2.3": "sha512",
"1.2.840.10045.4.3.4": "sha512ECDSA",
"1.2.840.113549.1.1.13": "sha512RSA",
"2.5.4.4": "SN",
"1.2.840.10045.4.3": "specifiedECDSA",
"2.5.4.9": "STREET",
"2.5.4.12": "T",
"2.23.133.2.1": "TPMManufacturer",
"2.23.133.2.2": "TPMModel",
"2.23.133.2.3": "TPMVersion",
"2.23.43.1.4.9": "wtls9",
"2.5.4.24": "X21Address",
"1.2.840.10045.3.1.2": "x962P192v2",
"1.2.840.10045.3.1.3": "x962P192v3",
"1.2.840.10045.3.1.4": "x962P239v1",
"1.2.840.10045.3.1.5": "x962P239v2",
"1.2.840.10045.3.1.6": "x962P239v3",
'1.2.840.113549.3.7': '3des',
'2.16.840.1.101.3.4.1.2': 'aes128',
'2.16.840.1.101.3.4.1.5': 'aes128wrap',
'2.16.840.1.101.3.4.1.22': 'aes192',
'2.16.840.1.101.3.4.1.25': 'aes192wrap',
'2.16.840.1.101.3.4.1.42': 'aes256',
'2.16.840.1.101.3.4.1.45': 'aes256wrap',
'1.3.36.3.3.2.8.1.1.1': 'brainpoolP160r1',
'1.3.36.3.3.2.8.1.1.2': 'brainpoolP160t1',
'1.3.36.3.3.2.8.1.1.3': 'brainpoolP192r1',
'1.3.36.3.3.2.8.1.1.4': 'brainpoolP192t1',
'1.3.36.3.3.2.8.1.1.5': 'brainpoolP224r1',
'1.3.36.3.3.2.8.1.1.6': 'brainpoolP224t1',
'1.3.36.3.3.2.8.1.1.7': 'brainpoolP256r1',
'1.3.36.3.3.2.8.1.1.8': 'brainpoolP256t1',
'1.3.36.3.3.2.8.1.1.9': 'brainpoolP320r1',
'1.3.36.3.3.2.8.1.1.10': 'brainpoolP320t1',
'1.3.36.3.3.2.8.1.1.11': 'brainpoolP384r1',
'1.3.36.3.3.2.8.1.1.12': 'brainpoolP384t1',
'1.3.36.3.3.2.8.1.1.13': 'brainpoolP512r1',
'1.3.36.3.3.2.8.1.1.14': 'brainpoolP512t1',
'2.5.4.6': 'C',
'1.2.840.113549.1.9.16.3.6': 'CMS3DESwrap',
'1.2.840.113549.1.9.16.3.7': 'CMSRC2wrap',
'2.5.4.3': 'CN',
'1.3.6.1.5.5.7.2.1': 'CPS',
'0.9.2342.19200300.100.1.25': 'DC',
'1.3.14.3.2.7': 'des',
'2.5.4.13': 'Description',
'1.2.840.10046.2.1': 'DH',
'2.5.4.46': 'dnQualifier',
'1.2.840.10040.4.1': 'DSA',
'1.3.14.3.2.27': 'dsaSHA1',
'1.2.840.113549.1.9.1': 'E',
'1.2.156.11235.1.1.2.1': 'ec192wapi',
'1.2.840.10045.2.1': 'ECC',
'1.3.133.16.840.63.0.2': 'ECDH_STD_SHA1_KDF',
'1.3.132.1.11.1': 'ECDH_STD_SHA256_KDF',
'1.3.132.1.11.2': 'ECDH_STD_SHA384_KDF',
'1.2.840.10045.3.1.7': 'ECDSA_P256',
'1.3.132.0.34': 'ECDSA_P384',
'1.3.132.0.35': 'ECDSA_P521',
'1.2.840.113549.1.9.16.3.5': 'ESDH',
'2.5.4.42': 'G',
'2.5.4.43': 'I',
'2.5.4.7': 'L',
'1.2.840.113549.2.2': 'md2',
'1.2.840.113549.1.1.2': 'md2RSA',
'1.2.840.113549.2.4': 'md4',
'1.2.840.113549.1.1.3': 'md4RSA',
'1.2.840.113549.2.5': 'md5',
'1.2.840.113549.1.1.4': 'md5RSA',
'1.2.840.113549.1.1.8': 'mgf1',
'2.16.840.1.101.2.1.1.20': 'mosaicKMandUpdSig',
'2.16.840.1.101.2.1.1.19': 'mosaicUpdatedSig',
'1.2.840.10045.3.1.1': 'nistP192',
'1.3.132.0.33': 'nistP224',
'1.3.6.1.5.5.7.6.2': 'NO_SIGN',
'2.5.4.10': 'O',
'2.5.4.11': 'OU',
'2.5.4.20': 'Phone',
'2.5.4.18': 'POBox',
'2.5.4.17': 'PostalCode',
'1.2.840.113549.3.2': 'rc2',
'1.2.840.113549.3.4': 'rc4',
'1.2.840.113549.1.1.1': 'RSA',
'1.2.840.113549.1.1.7': 'RSAES_OAEP',
'1.2.840.113549.1.1.10': 'RSASSA_PSS',
'2.5.4.8': 'S',
'1.3.132.0.9': 'secP160k1',
'1.3.132.0.8': 'secP160r1',
'1.3.132.0.30': 'secP160r2',
'1.3.132.0.31': 'secP192k1',
'1.3.132.0.32': 'secP224k1',
'1.3.132.0.10': 'secP256k1',
'2.5.4.5': 'SERIALNUMBER',
'1.3.14.3.2.26': 'sha1',
'1.2.840.10040.4.3': 'sha1DSA',
'1.2.840.10045.4.1': 'sha1ECDSA',
'1.2.840.113549.1.1.5': 'sha1RSA',
'2.16.840.1.101.3.4.2.1': 'sha256',
'1.2.840.10045.4.3.2': 'sha256ECDSA',
'1.2.840.113549.1.1.11': 'sha256RSA',
'2.16.840.1.101.3.4.2.2': 'sha384',
'1.2.840.10045.4.3.3': 'sha384ECDSA',
'1.2.840.113549.1.1.12': 'sha384RSA',
'2.16.840.1.101.3.4.2.3': 'sha512',
'1.2.840.10045.4.3.4': 'sha512ECDSA',
'1.2.840.113549.1.1.13': 'sha512RSA',
'2.5.4.4': 'SN',
'1.2.840.10045.4.3': 'specifiedECDSA',
'2.5.4.9': 'STREET',
'2.5.4.12': 'T',
'2.23.133.2.1': 'TPMManufacturer',
'2.23.133.2.2': 'TPMModel',
'2.23.133.2.3': 'TPMVersion',
'2.23.43.1.4.9': 'wtls9',
'2.5.4.24': 'X21Address',
'1.2.840.10045.3.1.2': 'x962P192v2',
'1.2.840.10045.3.1.3': 'x962P192v3',
'1.2.840.10045.3.1.4': 'x962P239v1',
'1.2.840.10045.3.1.5': 'x962P239v2',
'1.2.840.10045.3.1.6': 'x962P239v3',
};
export const mapSecpCurves: { [key: string]: string } = {
"ECDSA_224": "secp224r1",
"ECDSA_P256": "secp256r1",
"ECDSA_P384": "secp384r1",
"ECDSA_P521": "secp521r1",
}
ECDSA_224: 'secp224r1',
ECDSA_P256: 'secp256r1',
ECDSA_P384: 'secp384r1',
ECDSA_P521: 'secp521r1',
};
function getFriendlyNameSecpCurves(friendlyName: string): string {
return mapSecpCurves[friendlyName] || friendlyName;
return mapSecpCurves[friendlyName] || friendlyName;
}
export function getFriendlyName(oid: string): string {
return getFriendlyNameSecpCurves(oidMap[oid]) || "Unknown Algorithm";
return getFriendlyNameSecpCurves(oidMap[oid]) || 'Unknown Algorithm';
}
export function extractHashFunction(friendlyName: string): string {
if (friendlyName.toLowerCase().includes('sha1')) {
return 'sha1'
}
if (friendlyName.toLowerCase().includes('sha256')) {
return 'sha256'
}
if (friendlyName.toLowerCase().includes('sha384')) {
return 'sha384'
}
if (friendlyName.toLowerCase().includes('sha512')) {
return 'sha512'
}
throw new Error("hash function not found in: " + friendlyName);
if (friendlyName.toLowerCase().includes('sha1')) {
return 'sha1';
}
if (friendlyName.toLowerCase().includes('sha256')) {
return 'sha256';
}
if (friendlyName.toLowerCase().includes('sha384')) {
return 'sha384';
}
if (friendlyName.toLowerCase().includes('sha512')) {
return 'sha512';
}
throw new Error('hash function not found in: ' + friendlyName);
return 'unknown'
}
return 'unknown';
}

View File

@@ -1,186 +1,50 @@
import * as asn1js from "asn1js";
import { Certificate, RSAPublicKey, RSASSAPSSParams } from "pkijs";
import { extractHashFunction, getFriendlyName } from "./oids";
import { CertificateData, PublicKeyDetailsECDSA, PublicKeyDetailsRSA, PublicKeyDetailsRSAPSS } from "./dataStructure";
import { getECDSACurveBits, identifyCurve, StandardCurve } from "./curves";
import { getIssuerCountryCode, getSubjectKeyIdentifier } from "./utils";
import fs from 'fs';
import { execSync } from 'child_process';
import { parseCertificateSimple } from "./parseCertificateSimple";
import { parseCertificateSimple } from './parseCertificateSimple';
import { CertificateData } from './dataStructure';
export function parseCertificate(pem: string, fileName: string): any {
let certificateData: CertificateData = {
id: '',
issuer: '',
validity: {
notBefore: '',
notAfter: ''
},
subjectKeyIdentifier: '',
authorityKeyIdentifier: '',
signatureAlgorithm: '',
hashAlgorithm: '',
publicKeyDetails: undefined,
rawPem: '',
rawTxt: ''
};
let certificateData: CertificateData = {
id: '',
issuer: '',
validity: {
notBefore: '',
notAfter: '',
},
subjectKeyIdentifier: '',
authorityKeyIdentifier: '',
signatureAlgorithm: '',
hashAlgorithm: '',
publicKeyDetails: undefined,
rawPem: '',
rawTxt: '',
};
try {
certificateData = parseCertificateSimple(pem);
const baseFileName = fileName.replace('.pem', '');
const tempCertPath = `/tmp/${baseFileName}.pem`;
const formattedPem = pem.includes('-----BEGIN CERTIFICATE-----')
? pem
: `-----BEGIN CERTIFICATE-----\n${pem}\n-----END CERTIFICATE-----`;
fs.writeFileSync(tempCertPath, formattedPem);
try {
certificateData = parseCertificateSimple(pem);
const tempCertPath = `/tmp/${fileName}.pem`;
fs.writeFileSync(tempCertPath, pem);
try {
const openSslOutput = execSync(`openssl x509 -in ${tempCertPath} -text -noout`).toString();
certificateData.rawTxt = openSslOutput;
} catch (error) {
console.error(`Error executing OpenSSL command: ${error}`);
certificateData.rawTxt = 'Error: Unable to generate human-readable format';
} finally {
fs.unlinkSync(tempCertPath);
}
return certificateData;
const openSslOutput = execSync(`openssl x509 -in ${tempCertPath} -text -noout`).toString();
certificateData.rawTxt = openSslOutput;
} catch (error) {
console.error(`Error processing certificate ${fileName}:`, error);
throw error;
}
}
function getParamsRSA(cert: Certificate): PublicKeyDetailsRSA {
const publicKeyValue = cert.subjectPublicKeyInfo.parsedKey as RSAPublicKey;
const modulusBytes = publicKeyValue.modulus.valueBlock.valueHexView;
const modulusHex = Buffer.from(modulusBytes).toString('hex');
const exponentBigInt = publicKeyValue.publicExponent.toBigInt();
const exponentDecimal = exponentBigInt.toString();
const actualBits = modulusBytes.length * 8;
return {
modulus: modulusHex,
exponent: exponentDecimal,
bits: actualBits.toString()
};
}
function getParamsRSAPSS(cert: Certificate): PublicKeyDetailsRSAPSS {
const { modulus, exponent, bits } = getParamsRSA(cert);
const sigAlgParams = cert.signatureAlgorithm.algorithmParams;
const pssParams = new RSASSAPSSParams({ schema: sigAlgParams });
const hashAlgorithm = getFriendlyName(pssParams.hashAlgorithm.algorithmId);
const mgf = getFriendlyName(pssParams.maskGenAlgorithm.algorithmId);
return {
modulus: modulus,
exponent: exponent,
bits: bits,
hashAlgorithm: hashAlgorithm,
mgf: mgf,
saltLength: pssParams.saltLength.toString()
};
}
function getParamsRSAPSS2(cert: Certificate): PublicKeyDetailsRSAPSS {
// Get the subjectPublicKey BitString
const spki = cert.subjectPublicKeyInfo;
const spkiValueHex = spki.subjectPublicKey.valueBlock.valueHexView;
// Parse the public key ASN.1 structure
const asn1PublicKey = asn1js.fromBER(spkiValueHex);
if (asn1PublicKey.offset === -1) {
throw new Error("Error parsing public key ASN.1 structure");
console.error(`Error executing OpenSSL command: ${error}`);
certificateData.rawTxt = 'Error: Unable to generate human-readable format';
} finally {
try {
fs.unlinkSync(tempCertPath);
} catch (e) {
// Ignore cleanup errors
}
}
// The public key is an RSAPublicKey structure
const rsaPublicKey = new RSAPublicKey({ schema: asn1PublicKey.result });
const modulusBytes = rsaPublicKey.modulus.valueBlock.valueHexView;
const modulusHex = Buffer.from(modulusBytes).toString('hex');
const exponentBigInt = rsaPublicKey.publicExponent.toBigInt();
const exponentDecimal = exponentBigInt.toString();
const actualBits = modulusBytes.length * 8;
const sigAlgParams = cert.signatureAlgorithm.algorithmParams;
const pssParams = new RSASSAPSSParams({ schema: sigAlgParams });
const hashAlgorithm = getFriendlyName(pssParams.hashAlgorithm.algorithmId);
const mgf = getFriendlyName(pssParams.maskGenAlgorithm.algorithmId);
return {
modulus: modulusHex,
exponent: exponentDecimal,
bits: actualBits.toString(),
hashAlgorithm: hashAlgorithm,
mgf: mgf,
saltLength: pssParams.saltLength.toString()
};
return certificateData;
} catch (error) {
console.error(`Error processing certificate ${fileName}:`, error);
throw error;
}
}
export function getParamsECDSA(cert: Certificate): PublicKeyDetailsECDSA {
try {
const algorithmParams = cert.subjectPublicKeyInfo.algorithm.algorithmParams;
if (!algorithmParams) {
console.log('No algorithm params found');
return { curve: 'Unknown', params: {} as StandardCurve, bits: 'Unknown' };
}
const params = asn1js.fromBER(algorithmParams.valueBeforeDecodeView).result;
const valueBlock: any = params.valueBlock;
if (valueBlock.value && valueBlock.value.length >= 5) {
const curveParams: StandardCurve = {} as StandardCurve;
// Field ID (index 1)
const fieldId = valueBlock.value[1];
if (fieldId && fieldId.valueBlock && fieldId.valueBlock.value) {
const fieldType = fieldId.valueBlock.value[0];
const prime = fieldId.valueBlock.value[1];
//curveParams.fieldType = fieldType.valueBlock.toString();
curveParams.p = Buffer.from(prime.valueBlock.valueHexView).toString('hex');
}
// Curve Coefficients (index 2)
const curveCoefficients = valueBlock.value[2];
if (curveCoefficients && curveCoefficients.valueBlock && curveCoefficients.valueBlock.value) {
const a = curveCoefficients.valueBlock.value[0];
const b = curveCoefficients.valueBlock.value[1];
curveParams.a = Buffer.from(a.valueBlock.valueHexView).toString('hex');
curveParams.b = Buffer.from(b.valueBlock.valueHexView).toString('hex');
}
// Base Point G (index 3)
const basePoint = valueBlock.value[3];
if (basePoint && basePoint.valueBlock) {
curveParams.G = Buffer.from(basePoint.valueBlock.valueHexView).toString('hex');
}
// Order n (index 4)
const order = valueBlock.value[4];
if (order && order.valueBlock) {
curveParams.n = Buffer.from(order.valueBlock.valueHexView).toString('hex');
}
if (valueBlock.value.length >= 6) {
// Cofactor h (index 5)
const cofactor = valueBlock.value[5];
if (cofactor && cofactor.valueBlock) {
curveParams.h = Buffer.from(cofactor.valueBlock.valueHexView).toString('hex');
}
}
else {
curveParams.h = '01';
}
const identifiedCurve = identifyCurve(curveParams);
return { curve: identifiedCurve, params: curveParams, bits: getECDSACurveBits(identifiedCurve) };
} else {
if (valueBlock.value) {
console.log(valueBlock.value);
}
else {
console.log('No value block found');
}
}
} catch (error) {
console.error('Error parsing EC parameters:', error);
return { curve: 'Error', params: {} as StandardCurve, bits: 'Unknown' };
}
}

View File

@@ -1,13 +1,17 @@
import * as asn1js from "asn1js";
import { Certificate, RSAPublicKey, RSASSAPSSParams } from "pkijs";
import { extractHashFunction, getFriendlyName } from "./oids";
import { CertificateData, PublicKeyDetailsECDSA, PublicKeyDetailsRSA, PublicKeyDetailsRSAPSS } from "./dataStructure";
import { getCurveForElliptic, getECDSACurveBits, identifyCurve, StandardCurve } from "./curves";
import { getIssuerCountryCode, getSubjectKeyIdentifier } from "./utils";
import elliptic from 'elliptic';
import { circuitNameFromMode } from "../../constants/constants";
import { Mode } from "../appType";
import * as asn1js from 'asn1js';
import { Certificate, RSAPublicKey, RSASSAPSSParams } from 'pkijs';
import { getFriendlyName } from './oids';
import {
CertificateData,
PublicKeyDetailsECDSA,
PublicKeyDetailsRSA,
PublicKeyDetailsRSAPSS,
} from './dataStructure';
import { getCurveForElliptic, getECDSACurveBits, identifyCurve, StandardCurve } from './curves';
import { getIssuerCountryCode, getSubjectKeyIdentifier } from './utils';
import { circuitNameFromMode } from '../../constants/constants';
import { Mode } from '../appType';
import { initElliptic } from './elliptic';
export function parseCertificateSimple(pem: string): CertificateData {
let certificateData: CertificateData = {
@@ -15,7 +19,7 @@ export function parseCertificateSimple(pem: string): CertificateData {
issuer: '',
validity: {
notBefore: '',
notAfter: ''
notAfter: '',
},
subjectKeyIdentifier: '',
authorityKeyIdentifier: '',
@@ -23,11 +27,11 @@ export function parseCertificateSimple(pem: string): CertificateData {
hashAlgorithm: '',
publicKeyDetails: undefined,
rawPem: '',
rawTxt: ''
rawTxt: '',
};
try {
const pemFormatted = pem.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n|\r)/g, "");
const binary = Buffer.from(pemFormatted, "base64");
const pemFormatted = pem.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n|\r)/g, '');
const binary = Buffer.from(pemFormatted, 'base64');
const arrayBuffer = new ArrayBuffer(binary.length);
const view = new Uint8Array(arrayBuffer);
for (let i = 0; i < binary.length; i++) {
@@ -44,43 +48,25 @@ export function parseCertificateSimple(pem: string): CertificateData {
const publicKeyAlgoFN = getFriendlyName(publicKeyAlgoOID);
const signatureAlgoOID = cert.signatureAlgorithm.algorithmId;
const signatureAlgoFN = getFriendlyName(signatureAlgoOID);
certificateData.hashAlgorithm = getHashAlgorithm(signatureAlgoFN);
let params;
if (publicKeyAlgoFN === 'RSA') {
if (signatureAlgoFN === 'RSASSA_PSS') {
certificateData.signatureAlgorithm = "rsapss";
params = getParamsRSAPSS(cert);
certificateData.hashAlgorithm = (params as PublicKeyDetailsRSAPSS).hashAlgorithm;
}
else {
certificateData.hashAlgorithm = extractHashFunction(signatureAlgoFN);
certificateData.signatureAlgorithm = "rsa";
params = getParamsRSA(cert);
}
}
else if (publicKeyAlgoFN === 'ECC') {
certificateData.hashAlgorithm = extractHashFunction(signatureAlgoFN);
certificateData.signatureAlgorithm = "ecdsa";
certificateData.signatureAlgorithm = 'rsa';
params = getParamsRSA(cert);
} else if (publicKeyAlgoFN === 'ECC') {
certificateData.signatureAlgorithm = 'ecdsa';
params = getParamsECDSA(cert);
}
else if (publicKeyAlgoFN === 'RSASSA_PSS') {
certificateData.signatureAlgorithm = "rsapss";
//different certificate structure than the RSA/RSAPSS mix, we can't retrieve the modulus the same way as for RSA
// console.log(cert);
//TODO: implement the parsing of the RSASSA_PSS certificate
params = getParamsRSAPSS2(cert);
}
else {
} else if (publicKeyAlgoFN === 'RSASSA_PSS') {
certificateData.signatureAlgorithm = 'rsapss';
params = getParamsRSAPSS(cert);
} else {
console.log(publicKeyAlgoFN);
}
certificateData.publicKeyDetails = params;
certificateData.issuer = getIssuerCountryCode(cert);;
certificateData.issuer = getIssuerCountryCode(cert);
certificateData.validity = {
notBefore: cert.notBefore.value.toString(),
notAfter: cert.notAfter.value.toString()
notAfter: cert.notAfter.value.toString(),
};
const ski = getSubjectKeyIdentifier(cert);
certificateData.id = ski.slice(0, 12);
@@ -91,17 +77,17 @@ export function parseCertificateSimple(pem: string): CertificateData {
certificateData.authorityKeyIdentifier = authorityKeyIdentifier;
// corner case for rsapss
if (certificateData.signatureAlgorithm === "rsapss" && !certificateData.hashAlgorithm) {
certificateData.hashAlgorithm = (certificateData.publicKeyDetails as PublicKeyDetailsRSAPSS).hashAlgorithm;
if (certificateData.signatureAlgorithm === 'rsapss' && !certificateData.hashAlgorithm) {
certificateData.hashAlgorithm = (
certificateData.publicKeyDetails as PublicKeyDetailsRSAPSS
).hashAlgorithm;
}
return certificateData;
} catch (error) {
console.error(`Error processing certificate`, error);
throw error;
}
}
function getParamsRSA(cert: Certificate): PublicKeyDetailsRSA {
@@ -115,28 +101,11 @@ function getParamsRSA(cert: Certificate): PublicKeyDetailsRSA {
return {
modulus: modulusHex,
exponent: exponentDecimal,
bits: actualBits.toString()
bits: actualBits.toString(),
};
}
function getParamsRSAPSS(cert: Certificate): PublicKeyDetailsRSAPSS {
const { modulus, exponent, bits } = getParamsRSA(cert);
const sigAlgParams = cert.signatureAlgorithm.algorithmParams;
const pssParams = new RSASSAPSSParams({ schema: sigAlgParams });
const hashAlgorithm = getFriendlyName(pssParams.hashAlgorithm.algorithmId);
const mgf = getFriendlyName(pssParams.maskGenAlgorithm.algorithmId);
return {
modulus: modulus,
exponent: exponent,
bits: bits,
hashAlgorithm: hashAlgorithm,
mgf: mgf,
saltLength: pssParams.saltLength.toString()
};
}
function getParamsRSAPSS2(cert: Certificate): PublicKeyDetailsRSAPSS {
// Get the subjectPublicKey BitString
const spki = cert.subjectPublicKeyInfo;
const spkiValueHex = spki.subjectPublicKey.valueBlock.valueHexView;
@@ -144,7 +113,7 @@ function getParamsRSAPSS2(cert: Certificate): PublicKeyDetailsRSAPSS {
// Parse the public key ASN.1 structure
const asn1PublicKey = asn1js.fromBER(spkiValueHex);
if (asn1PublicKey.offset === -1) {
throw new Error("Error parsing public key ASN.1 structure");
throw new Error('Error parsing public key ASN.1 structure');
}
// The public key is an RSAPublicKey structure
@@ -166,21 +135,29 @@ function getParamsRSAPSS2(cert: Certificate): PublicKeyDetailsRSAPSS {
bits: actualBits.toString(),
hashAlgorithm: hashAlgorithm,
mgf: mgf,
saltLength: pssParams.saltLength.toString()
saltLength: pssParams.saltLength.toString(),
};
}
export function getParamsECDSA(cert: Certificate): PublicKeyDetailsECDSA {
try {
const algorithmParams = cert.subjectPublicKeyInfo.algorithm.algorithmParams;
if (!algorithmParams) {
console.log('No algorithm params found');
return { curve: 'Unknown', params: {} as StandardCurve, bits: 'Unknown', x: 'Unknown', y: 'Unknown' };
console.error('No algorithm params found');
return {
curve: 'Unknown',
params: {} as StandardCurve,
bits: 'Unknown',
x: 'Unknown',
y: 'Unknown',
};
}
let curveName, bits, x, y = 'Unknown';
let curveName,
bits,
x,
y = 'Unknown';
let curveParams: StandardCurve = {} as StandardCurve;
// Try to get the curve name from the OID
@@ -207,7 +184,11 @@ export function getParamsECDSA(cert: Certificate): PublicKeyDetailsECDSA {
// Curve Coefficients (index 2)
const curveCoefficients = valueBlock.value[2];
if (curveCoefficients && curveCoefficients.valueBlock && curveCoefficients.valueBlock.value) {
if (
curveCoefficients &&
curveCoefficients.valueBlock &&
curveCoefficients.valueBlock.value
) {
const a = curveCoefficients.valueBlock.value[0];
const b = curveCoefficients.valueBlock.value[1];
curveParams.a = Buffer.from(a.valueBlock.valueHexView).toString('hex');
@@ -232,8 +213,7 @@ export function getParamsECDSA(cert: Certificate): PublicKeyDetailsECDSA {
if (cofactor && cofactor.valueBlock) {
curveParams.h = Buffer.from(cofactor.valueBlock.valueHexView).toString('hex');
}
}
else {
} else {
curveParams.h = '01';
}
const identifiedCurve = identifyCurve(curveParams);
@@ -242,8 +222,7 @@ export function getParamsECDSA(cert: Certificate): PublicKeyDetailsECDSA {
} else {
if (valueBlock.value) {
console.log(valueBlock.value);
}
else {
} else {
console.log('No value block found');
}
}
@@ -252,18 +231,22 @@ export function getParamsECDSA(cert: Certificate): PublicKeyDetailsECDSA {
// Get the public key x and y parameters
const publicKeyBuffer = cert.subjectPublicKeyInfo.subjectPublicKey.valueBlock.valueHexView;
if (publicKeyBuffer && curveName !== 'Unknown') {
const elliptic = initElliptic();
const ec = new elliptic.ec(getCurveForElliptic(curveName));
const key = ec.keyFromPublic(publicKeyBuffer);
x = key.getPublic().getX().toString('hex');
y = key.getPublic().getY().toString('hex');
}
return { curve: curveName, params: curveParams, bits: bits, x: x, y: y };
} catch (error) {
console.error('Error parsing EC parameters:', error);
return { curve: 'Error', params: {} as StandardCurve, bits: 'Unknown', x: 'Unknown', y: 'Unknown' };
return {
curve: 'Error',
params: {} as StandardCurve,
bits: 'Unknown',
x: 'Unknown',
y: 'Unknown',
};
}
}
@@ -282,7 +265,7 @@ export const getAuthorityKeyIdentifier = (cert: Certificate): string => {
};
export const getCircuitName = (
circuitMode: "prove" | "dsc" | "vc_and_disclose",
circuitMode: 'prove' | 'dsc' | 'vc_and_disclose',
signatureAlgorithm: string,
hashFunction: string,
domainParameter: string,
@@ -317,15 +300,32 @@ export const getCircuitName = (
keyLength
);
};
export const getCircuitNameOld = (circuitMode: Mode, signatureAlgorithm: string, hashFunction: string) => {
export const getCircuitNameOld = (
circuitMode: Mode,
signatureAlgorithm: string,
hashFunction: string
) => {
const circuit = circuitNameFromMode[circuitMode];
if (circuit == 'vc_and_disclose') {
return 'vc_and_disclose';
} else if (signatureAlgorithm === 'ecdsa') {
return circuit + '_' + signatureAlgorithm + '_secp256r1_' + hashFunction;
} else {
return circuit + '_' + signatureAlgorithm + '_65537_' + hashFunction;
}
else if (signatureAlgorithm === 'ecdsa') {
return circuit + "_" + signatureAlgorithm + "_secp256r1_" + hashFunction;
};
export function getHashAlgorithm(rawSignatureAlgorithm: string) {
const input = rawSignatureAlgorithm.toLowerCase();
const patterns = [/sha-?1/i, /sha-?256/i, /sha-?384/i, /sha-?512/i];
for (const pattern of patterns) {
const match = input.match(pattern);
if (match) {
// Remove any hyphens and return standardized format
return match[0].replace('-', '');
}
}
else {
return circuit + "_" + signatureAlgorithm + "_65537_" + hashFunction;
}
}
return 'unknown';
}

View File

@@ -1,53 +1,57 @@
import { asn1 } from "node-forge";
import * as asn1js from "asn1js";
import { Certificate } from "pkijs";
import * as asn1js from 'asn1js';
import { Certificate } from 'pkijs';
import { sha256 } from 'js-sha256';
export const getSubjectKeyIdentifier = (cert: Certificate): string => {
const subjectKeyIdentifier = cert.extensions.find(
(ext) => ext.extnID === '2.5.29.14'
const subjectKeyIdentifier = cert.extensions.find((ext) => ext.extnID === '2.5.29.14');
if (subjectKeyIdentifier) {
let skiValue = Buffer.from(subjectKeyIdentifier.extnValue.valueBlock.valueHexView).toString(
'hex'
);
if (subjectKeyIdentifier) {
let skiValue = Buffer.from(subjectKeyIdentifier.extnValue.valueBlock.valueHexView).toString('hex');
skiValue = skiValue.replace(/^(?:3016)?(?:0414)?/, '');
return skiValue
} else {
// do a sha1 of the certificate tbs
const hash = sha256.create();
hash.update(cert.tbsView);
return hash.hex();
}
}
skiValue = skiValue.replace(/^(?:3016)?(?:0414)?/, '');
return skiValue;
} else {
console.log('\x1b[31m%s\x1b[0m', 'no subject key identifier found');
// do a sha1 of the certificate tbs
const hash = sha256.create();
hash.update(cert.tbsView);
return hash.hex();
}
};
export const getAuthorityKeyIdentifier = (cert: Certificate): string => {
const authorityKeyIdentifierExt = cert.extensions.find(ext => ext.extnID === '2.5.29.35');
if (authorityKeyIdentifierExt) {
const extnValueHex = authorityKeyIdentifierExt.extnValue.valueBlock.valueHexView;
const asn1 = asn1js.fromBER(extnValueHex);
if (asn1.offset !== -1) {
const constructedValue = asn1.result.valueBlock as { value: Array<any> };
if (constructedValue.value) {
const keyIdentifierElement = constructedValue.value.find(
element => element.idBlock.tagClass === 3 && element.idBlock.tagNumber === 0
);
if (keyIdentifierElement) {
return Buffer.from(keyIdentifierElement.valueBlock.valueHexView).toString('hex');
}
}
const authorityKeyIdentifierExt = cert.extensions.find((ext) => ext.extnID === '2.5.29.35');
if (authorityKeyIdentifierExt) {
const extnValueHex = authorityKeyIdentifierExt.extnValue.valueBlock.valueHexView;
const asn1 = asn1js.fromBER(extnValueHex);
if (asn1.offset !== -1) {
const constructedValue = asn1.result.valueBlock as { value: Array<any> };
if (constructedValue.value) {
const keyIdentifierElement = constructedValue.value.find(
(element) => element.idBlock.tagClass === 3 && element.idBlock.tagNumber === 0
);
if (keyIdentifierElement) {
return Buffer.from(keyIdentifierElement.valueBlock.valueHexView).toString('hex');
}
}
}
return '';
}
else {
console.log('\x1b[31m%s\x1b[0m', 'no authority key identifier found');
}
return '';
};
export function getIssuerCountryCode(cert: Certificate): string {
const issuerRDN = cert.issuer.typesAndValues;
let issuerCountryCode = '';
for (const rdn of issuerRDN) {
if (rdn.type === '2.5.4.6') { // OID for Country Name
issuerCountryCode = rdn.value.valueBlock.value;
break;
}
const issuerRDN = cert.issuer.typesAndValues;
let issuerCountryCode = '';
for (const rdn of issuerRDN) {
if (rdn.type === '2.5.4.6') {
// OID for Country Name
issuerCountryCode = rdn.value.valueBlock.value;
break;
}
return issuerCountryCode.toUpperCase();
}
}
return issuerCountryCode.toUpperCase();
}

View File

@@ -0,0 +1,41 @@
import { PassportData } from './types';
import { parsePassportData } from './parsePassportData';
import { parseCertificateSimple } from './certificate_parsing/parseCertificateSimple';
import {
PublicKeyDetailsECDSA,
PublicKeyDetailsRSA,
PublicKeyDetailsRSAPSS,
} from './certificate_parsing/dataStructure';
export function getCircuitNameFromPassportData(passportData: PassportData) {
const passportMetadata = parsePassportData(passportData);
const parsedDsc = parseCertificateSimple(passportData.dsc);
const dgHashAlgo = passportMetadata.dg1HashFunction;
const eContentHashAlgo = passportMetadata.eContentHashFunction;
const signedAttrHashAlgo = passportMetadata.signedAttrHashFunction;
const sigAlg = passportMetadata.signatureAlgorithm;
if (parsedDsc.signatureAlgorithm === 'ecdsa') {
const curve = (parsedDsc.publicKeyDetails as PublicKeyDetailsECDSA).curve;
return `prove_${dgHashAlgo}_${eContentHashAlgo}_${signedAttrHashAlgo}_${sigAlg}_${curve}`;
} else if (parsedDsc.signatureAlgorithm === 'rsa') {
const exponent = (parsedDsc.publicKeyDetails as PublicKeyDetailsRSA).exponent;
const bits = (parsedDsc.publicKeyDetails as PublicKeyDetailsRSA).bits;
if (parseInt(bits) <= 4096) {
return `prove_${dgHashAlgo}_${eContentHashAlgo}_${signedAttrHashAlgo}_${sigAlg}_${exponent}_${4096}`;
} else {
throw new Error(`Unsupported key length: ${bits}`);
}
} else if (parsedDsc.signatureAlgorithm === 'rsapss') {
const exponent = (parsedDsc.publicKeyDetails as PublicKeyDetailsRSA).exponent;
const saltLength = (parsedDsc.publicKeyDetails as PublicKeyDetailsRSAPSS).saltLength;
const bits = (parsedDsc.publicKeyDetails as PublicKeyDetailsRSAPSS).bits;
if (parseInt(bits) <= 4096) {
return `prove_${dgHashAlgo}_${eContentHashAlgo}_${signedAttrHashAlgo}_${sigAlg}_${exponent}_${saltLength}_${4096}`;
} else {
throw new Error(`Unsupported key length: ${bits}`);
}
} else {
throw new Error('Unsupported signature algorithm');
}
}

View File

@@ -1,13 +1,6 @@
import { shaPad } from './shaPad';
import * as forge from 'node-forge';
import {
bytesToBigDecimal,
extractRSFromSignature,
getNAndK,
getNAndKCSCA,
hexToDecimal,
splitToWords,
} from './utils';
import { bytesToBigDecimal, getNAndK, getNAndKCSCA, hexToDecimal, splitToWords } from './utils';
import { CSCA_TREE_DEPTH, MODAL_SERVER_ADDRESS } from '../constants/constants';
import { poseidon2 } from 'poseidon-lite';
import { IMT } from '@openpassport/zk-kit-imt';
@@ -65,42 +58,42 @@ export function generateCircuitInputsDSC(
dscTbsCertBytes.map((byte) => parseInt(byte.toString(16), 16))
);
const {
signatureAlgorithm,
hashAlgorithm,
authorityKeyIdentifier,
publicKeyDetails
} = parseCertificateSimple(dscCertificate);
console.log("authorityKeyIdentifier", authorityKeyIdentifier);
const { signatureAlgorithm, hashAlgorithm, authorityKeyIdentifier, publicKeyDetails } =
parseCertificateSimple(dscCertificate);
console.log('authorityKeyIdentifier', authorityKeyIdentifier);
let dsc_message_padded;
let dsc_messagePaddedLen;
[dsc_message_padded, dsc_messagePaddedLen] = shaPad(dscTbsCertUint8Array, max_cert_bytes);
console.log("signatureAlgorithm: ", signatureAlgorithm);
console.log('signatureAlgorithm: ', signatureAlgorithm);
const { n, k } = getNAndK(signatureAlgorithm as SignatureAlgorithm);
const dscSignature = dscCert.signature;
const encryptedDigest = Array.from(forge.util.createBuffer(dscSignature).getBytes(), (char) =>
char.charCodeAt(0)
);
let pubKey_dsc, signature, startIndex, dsc_message_padded_formatted, dsc_messagePaddedLen_formatted: any;
let pubKey_dsc,
signature,
startIndex,
dsc_message_padded_formatted,
dsc_messagePaddedLen_formatted: any;
let curve, exponent;
if (signatureAlgorithm === 'rsa' || signatureAlgorithm === 'rsapss') {
const modulus = (publicKeyDetails as PublicKeyDetailsRSA).modulus;
exponent = (publicKeyDetails as PublicKeyDetailsRSA).exponent;
startIndex = findStartIndex((publicKeyDetails as PublicKeyDetailsRSA).modulus, dsc_message_padded).toString();
startIndex = findStartIndex(
(publicKeyDetails as PublicKeyDetailsRSA).modulus,
dsc_message_padded
).toString();
dsc_message_padded_formatted = Array.from(dsc_message_padded).map((x) => x.toString());
dsc_messagePaddedLen_formatted = BigInt(dsc_messagePaddedLen).toString();
console.log("\x1b[34m", "startIndex: ", startIndex, "\x1b[0m");
console.log('\x1b[34m', 'startIndex: ', startIndex, '\x1b[0m');
pubKey_dsc = formatInput(splitToWords(BigInt(hexToDecimal(modulus)), n, k));
}
else {
console.log("\x1b[34m", "signatureAlgorithm: ", signatureAlgorithm, "\x1b[0m");
} else {
console.log('\x1b[34m', 'signatureAlgorithm: ', signatureAlgorithm, '\x1b[0m');
// TODO: implement ecdsa
// const { r, s } = extractRSFromSignature(encryptedDigest);
// const signature_r = splitToWords(BigInt(hexToDecimal(r)), n_csca, k_csca);
@@ -119,7 +112,6 @@ export function generateCircuitInputsDSC(
const leaf = getLeafCSCA(cscaPem);
const [root, proof] = getCSCAModulusProof(leaf);
const parsedCSCAPem: CertificateData = parseCertificateSimple(cscaPem);
let csca_pubKey_formatted;
@@ -131,15 +123,13 @@ export function generateCircuitInputsDSC(
char.charCodeAt(0)
);
signature = formatInput(splitToWords(BigInt(bytesToBigDecimal(signature_raw)), n_csca, k_csca));
} else {
// const csca_x_formatted = splitToWords(BigInt(hexToDecimal(csca_x)), n_csca, k_csca);
// const csca_y_formatted = splitToWords(BigInt(hexToDecimal(csca_y)), n_csca, k_csca);
// csca_pubKey_formatted = [...csca_x_formatted, ...csca_y_formatted];
}
console.log('dsc_pubKey_length', pubKey_dsc.length);
return {
signature_algorithm: `${signatureAlgorithm}_${curve || exponent}_${hashAlgorithm}_${4096}`,
inputs: {
@@ -152,21 +142,30 @@ export function generateCircuitInputsDSC(
secret: [dscSecret],
merkle_root: [BigInt(root).toString()],
path: proof.pathIndices.map((index) => index.toString()),
siblings: proof.siblings.flat().map((sibling) => sibling.toString())
siblings: proof.siblings.flat().map((sibling) => sibling.toString()),
},
};
}
export function getCSCAFromSKI(ski: string, devMode: boolean): string {
const cscaPemPROD = (SKI_PEM as any)[ski];
const cscaPemDEV = (SKI_PEM_DEV as any)[ski];
const cscaPem = devMode ? cscaPemDEV || cscaPemPROD : cscaPemPROD;
const normalizedSki = ski.replace(/\s+/g, '').toLowerCase();
const cscaPemPROD = (SKI_PEM as any)[normalizedSki];
const cscaPemDEV = (SKI_PEM_DEV as any)[normalizedSki];
let cscaPem = devMode ? cscaPemDEV || cscaPemPROD : cscaPemPROD;
if (!cscaPem) {
console.log('\x1b[31m%s\x1b[0m', `CSCA with SKI ${ski} not found`, 'devMode: ', devMode);
console.log('\x1b[33m%s\x1b[0m', `[WRN] CSCA with SKI ${ski} not found`, 'devMode: ', devMode);
throw new Error(
`CSCA not found, authorityKeyIdentifier: ${ski}, areMockPassportsAllowed: ${devMode},`
`CSCA not found, authorityKeyIdentifier: ${ski}, areMockPassportsAllowed: ${devMode}`
);
}
if (!cscaPem.includes('-----BEGIN CERTIFICATE-----')) {
cscaPem = `-----BEGIN CERTIFICATE-----\n${cscaPem}\n-----END CERTIFICATE-----`;
}
return cscaPem;
}

View File

@@ -1,5 +1,11 @@
import { PassportData } from './types';
import { hash, assembleEContent, formatAndConcatenateDataHashes, formatMrz, getHashLen } from './utils';
import {
hash,
generateSignedAttr,
formatAndConcatenateDataHashes,
formatMrz,
getHashLen,
} from './utils';
import * as forge from 'node-forge';
import * as asn1 from 'asn1js';
import elliptic from 'elliptic';
@@ -34,14 +40,56 @@ import {
mock_dsc_sha256_rsapss_65537_3072,
mock_dsc_key_rsapss_65537_4096,
mock_dsc_sha256_rsapss_65537_4096,
mock_dsc_key_sha384_brainpoolP384r1,
mock_dsc_sha384_brainpoolP384r1,
mock_dsc_key_sha256_secp384r1,
mock_dsc_sha256_secp384r1,
mock_dsc_key_sha384_brainpoolP256r1,
mock_dsc_sha384_brainpoolP256r1,
mock_dsc_key_sha512_brainpoolP256r1,
mock_dsc_sha512_brainpoolP256r1,
mock_dsc_key_sha512_brainpoolP384r1,
mock_dsc_sha512_brainpoolP384r1,
mock_dsc_key_sha1_brainpoolP224r1,
mock_dsc_sha1_brainpoolP224r1,
mock_dsc_key_sha256_brainpoolP224r1,
mock_dsc_sha256_brainpoolP224r1,
mock_dsc_key_sha512_brainpoolP512r1,
mock_dsc_sha512_brainpoolP512r1,
mock_dsc_key_sha224_braipoolP224r1,
mock_dsc_sha224_brainpoolP224r1,
} from '../constants/mockCertificates';
import { sampleDataHashes_small, sampleDataHashes_large } from '../constants/sampleDataHashes';
import { countryCodes } from '../constants/constants';
import { parseCertificateSimple } from './certificate_parsing/parseCertificateSimple';
import { SignatureAlgorithm } from './types';
import { PublicKeyDetailsECDSA } from './certificate_parsing/dataStructure';
import { PublicKeyDetailsECDSA, PublicKeyDetailsRSAPSS } from './certificate_parsing/dataStructure';
import { getCurveForElliptic } from './certificate_parsing/curves';
function generateRandomBytes(length: number): number[] {
// Generate numbers between -128 and 127 to match the existing signed byte format
return Array.from({ length }, () => Math.floor(Math.random() * 256) - 128);
}
function generateDataGroupHashes(mrzHash: number[], hashLen: number): [number, number[]][] {
// Generate hashes for DGs 2-15 (excluding some DGs that aren't typically used)
const dataGroups: [number, number[]][] = [
[1, mrzHash], // DG1 must be the MRZ hash
[2, generateRandomBytes(hashLen)],
[3, generateRandomBytes(hashLen)],
[4, generateRandomBytes(hashLen)],
[5, generateRandomBytes(hashLen)],
[7, generateRandomBytes(hashLen)],
[11, generateRandomBytes(hashLen)],
[12, generateRandomBytes(hashLen)],
[14, generateRandomBytes(hashLen)],
];
return dataGroups;
}
export function genMockPassportData(
dgHashAlgo: string,
eContentHashAlgo: string,
signatureType: SignatureAlgorithm,
nationality: keyof typeof countryCodes,
birthDate: string,
@@ -91,112 +139,134 @@ export function genMockPassportData(
let privateKeyPem: string;
let dsc: string;
let sampleDataHashes: [number, number[]][];
switch (signatureType) {
case 'rsa_sha1_65537_2048':
sampleDataHashes = sampleDataHashes_small;
privateKeyPem = mock_dsc_key_sha1_rsa_4096;
dsc = mock_dsc_sha1_rsa_4096;
break;
case 'rsa_sha256_65537_2048':
sampleDataHashes = sampleDataHashes_large;
privateKeyPem = mock_dsc_key_sha256_rsa_4096;
dsc = mock_dsc_sha256_rsa_4096;
break;
case 'rsapss_sha256_65537_2048':
sampleDataHashes = sampleDataHashes_large;
privateKeyPem = mock_dsc_key_sha256_rsapss_4096;
dsc = mock_dsc_sha256_rsapss_4096;
break;
case 'rsapss_sha256_3_4096':
sampleDataHashes = sampleDataHashes_large;
privateKeyPem = mock_dsc_key_sha256_rsapss_3_4096;
dsc = mock_dsc_sha256_rsapss_3_4096;
break;
case 'rsapss_sha256_3_3072':
sampleDataHashes = sampleDataHashes_large;
privateKeyPem = mock_dsc_key_sha256_rsapss_3_3072;
dsc = mock_dsc_sha256_rsapss_3_3072;
break;
case 'rsapss_sha384_65537_3072':
sampleDataHashes = sampleDataHashes_large;
privateKeyPem = mock_dsc_key_sha384_rsapss_65537_3072;
dsc = mock_dsc_sha384_rsapss_65537_3072;
break;
case 'ecdsa_sha256_secp256r1_256':
sampleDataHashes = sampleDataHashes_large;
privateKeyPem = mock_dsc_key_sha256_ecdsa;
dsc = mock_dsc_sha256_ecdsa;
break;
case 'ecdsa_sha1_secp256r1_256':
sampleDataHashes = sampleDataHashes_small;
privateKeyPem = mock_dsc_key_sha1_ecdsa;
dsc = mock_dsc_sha1_ecdsa;
break;
case 'ecdsa_sha384_secp384r1_384':
sampleDataHashes = sampleDataHashes_small;
privateKeyPem = mock_dsc_key_sha384_ecdsa;
dsc = mock_dsc_sha384_ecdsa;
break;
case 'ecdsa_sha256_secp384r1_384':
privateKeyPem = mock_dsc_key_sha256_secp384r1;
dsc = mock_dsc_sha256_secp384r1;
break;
case 'ecdsa_sha256_brainpoolP256r1_256':
sampleDataHashes = sampleDataHashes_small;
privateKeyPem = mock_dsc_key_sha256_brainpoolP256r1;
dsc = mock_dsc_sha256_brainpoolP256r1;
break;
case 'ecdsa_sha384_brainpoolP256r1_256':
privateKeyPem = mock_dsc_key_sha384_brainpoolP256r1;
dsc = mock_dsc_sha384_brainpoolP256r1;
break;
case 'ecdsa_sha512_brainpoolP256r1_256':
privateKeyPem = mock_dsc_key_sha512_brainpoolP256r1;
dsc = mock_dsc_sha512_brainpoolP256r1;
break;
case 'rsa_sha256_3_2048':
sampleDataHashes = sampleDataHashes_large;
privateKeyPem = mock_dsc_key_sha256_rsa_3_2048;
dsc = mock_dsc_sha256_rsa_3_2048;
break;
case 'rsa_sha256_65537_3072':
sampleDataHashes = sampleDataHashes_large;
privateKeyPem = mock_dsc_key_sha256_rsa_65537_3072;
dsc = mock_dsc_sha256_rsa_65537_3072;
break;
case 'rsapss_sha256_65537_3072':
sampleDataHashes = sampleDataHashes_large;
privateKeyPem = mock_dsc_key_sha256_rsapss_65537_3072;
dsc = mock_dsc_sha256_rsapss_65537_3072;
break;
case 'rsapss_sha256_65537_4096':
sampleDataHashes = sampleDataHashes_large;
privateKeyPem = mock_dsc_key_rsapss_65537_4096;
dsc = mock_dsc_sha256_rsapss_65537_4096;
break;
case 'ecdsa_sha384_brainpoolP384r1_384':
privateKeyPem = mock_dsc_key_sha384_brainpoolP384r1;
dsc = mock_dsc_sha384_brainpoolP384r1;
break;
case 'ecdsa_sha512_brainpoolP384r1_384':
privateKeyPem = mock_dsc_key_sha512_brainpoolP384r1;
dsc = mock_dsc_sha512_brainpoolP384r1;
break;
case 'ecdsa_sha1_brainpoolP224r1_224':
privateKeyPem = mock_dsc_key_sha1_brainpoolP224r1;
dsc = mock_dsc_sha1_brainpoolP224r1;
break;
case 'ecdsa_sha224_brainpoolP224r1_224':
privateKeyPem = mock_dsc_key_sha224_braipoolP224r1;
dsc = mock_dsc_sha224_brainpoolP224r1;
break;
case 'ecdsa_sha256_brainpoolP224r1_224':
privateKeyPem = mock_dsc_key_sha256_brainpoolP224r1;
dsc = mock_dsc_sha256_brainpoolP224r1;
break;
case 'ecdsa_sha512_brainpoolP512r1_512':
privateKeyPem = mock_dsc_key_sha512_brainpoolP512r1;
dsc = mock_dsc_sha512_brainpoolP512r1;
break;
}
const parsedDsc = parseCertificateSimple(dsc);
const hashAlgorithm = parsedDsc.hashAlgorithm;
// Generate MRZ hash first
const mrzHash = hash(dgHashAlgo, formatMrz(mrz));
const mrzHash = hash(hashAlgorithm, formatMrz(mrz));
const hashLen = getHashLen(hashAlgorithm);
const concatenatedDataHashes = formatAndConcatenateDataHashes(
[[1, mrzHash], ...sampleDataHashes],
hashLen,
30
);
// Generate random hashes for other DGs, passing mrzHash for DG1
const dataGroupHashes = generateDataGroupHashes(mrzHash as number[], getHashLen(dgHashAlgo));
const eContent = assembleEContent(hash(hashAlgorithm, concatenatedDataHashes));
const eContent = formatAndConcatenateDataHashes(dataGroupHashes, 63);
const signature = sign(privateKeyPem, dsc, eContent);
const signedAttr = generateSignedAttr(hash(eContentHashAlgo, eContent) as number[]);
const hashAlgo = signatureType.split('_')[1];
const signature = sign(privateKeyPem, dsc, hashAlgo, signedAttr);
const signatureBytes = Array.from(signature, (byte) => (byte < 128 ? byte : byte - 256));
return {
dsc: dsc,
mrz: mrz,
dg2Hash: sampleDataHashes[0][1],
eContent: concatenatedDataHashes,
signedAttr: eContent,
dg2Hash: dataGroupHashes.find(([dgNum]) => dgNum === 2)?.[1] || [],
eContent: eContent,
signedAttr: signedAttr,
encryptedDigest: signatureBytes,
photoBase64: 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABjElEQVR42mL8//8/AyUYiBQYmIy3...',
mockUser: true,
};
}
function sign(privateKeyPem: string, dsc: string, eContent: number[]): number[] {
const { signatureAlgorithm, hashAlgorithm, publicKeyDetails } = parseCertificateSimple(dsc);
const curve = (publicKeyDetails as PublicKeyDetailsECDSA).curve;
function sign(
privateKeyPem: string,
dsc: string,
hashAlgorithm: string,
eContent: number[]
): number[] {
const { signatureAlgorithm, publicKeyDetails } = parseCertificateSimple(dsc);
if (signatureAlgorithm === 'rsapss') {
const privateKey = forge.pki.privateKeyFromPem(privateKeyPem);
@@ -205,11 +275,12 @@ function sign(privateKeyPem: string, dsc: string, eContent: number[]): number[]
const pss = forge.pss.create({
md: forge.md.sha256.create(),
mgf: forge.mgf.mgf1.create(forge.md.sha256.create()),
saltLength: 32,
saltLength: parseInt((publicKeyDetails as PublicKeyDetailsRSAPSS).saltLength),
});
const signatureBytes = privateKey.sign(md, pss);
return Array.from(signatureBytes, (c: string) => c.charCodeAt(0));
} else if (signatureAlgorithm === 'ecdsa') {
const curve = (publicKeyDetails as PublicKeyDetailsECDSA).curve;
let curveForElliptic = getCurveForElliptic(curve);
const ec = new elliptic.ec(curveForElliptic);
@@ -219,22 +290,13 @@ function sign(privateKeyPem: string, dsc: string, eContent: number[]): number[]
);
const asn1Data = asn1.fromBER(privateKeyDer);
const privateKeyBuffer = (asn1Data.result.valueBlock as any).value[1].valueBlock.valueHexView;
// console.log('sig deets');
// console.log('pk', privateKeyBuffer);
// console.log('hashFUnction', hashAlgorithm);
// console.log('message', Buffer.from(eContent).toString('hex'));
const keyPair = ec.keyFromPrivate(privateKeyBuffer);
let md = forge.md[hashAlgorithm].create();
md.update(forge.util.binary.raw.encode(new Uint8Array(eContent)));
const msgHash = hash(hashAlgorithm, eContent, 'hex');
console.log('message to sign', md.digest().toHex());
const signature = keyPair.sign(md.digest().toHex(), 'hex');
console.log(Buffer.from(signature.toDER(), 'hex').toString('hex'));
const signature = keyPair.sign(msgHash, 'hex');
const signatureBytes = Array.from(Buffer.from(signature.toDER(), 'hex'));
console.log('sig', JSON.stringify(signatureBytes));
return signatureBytes;
} else {
const privKey = forge.pki.privateKeyFromPem(privateKeyPem);
@@ -243,4 +305,4 @@ function sign(privateKeyPem: string, dsc: string, eContent: number[]): number[]
const forgeSignature = privKey.sign(md);
return Array.from(forgeSignature, (c: string) => c.charCodeAt(0));
}
}
}

View File

@@ -4,7 +4,7 @@ import {
MAX_PADDED_ECONTENT_LEN,
MAX_PADDED_SIGNED_ATTR_LEN,
} from '../constants/constants';
import { assert, shaPad } from './shaPad';
import { assert, sha384_512Pad, shaPad } from './shaPad';
import { PassportData, SignatureAlgorithm } from './types';
import {
bytesToBigDecimal,
@@ -32,7 +32,7 @@ import { packBytes } from '../utils/utils';
import { SMT } from '@openpassport/zk-kit-smt';
import { parseCertificateSimple } from './certificate_parsing/parseCertificateSimple';
import { PublicKeyDetailsECDSA, PublicKeyDetailsRSA } from './certificate_parsing/dataStructure';
import { cp } from 'fs';
import { parsePassportData } from './parsePassportData';
export function generateCircuitInputsDisclose(
secret: string,
@@ -183,15 +183,13 @@ export function generateCircuitInputsProve(
user_identifier_type: 'uuid' | 'hex' | 'ascii' = DEFAULT_USER_ID_TYPE
) {
const { mrz, eContent, signedAttr, encryptedDigest, dsc, dg2Hash } = passportData;
const { signatureAlgorithm, hashAlgorithm, publicKeyDetails } = parseCertificateSimple(passportData.dsc);
const passportMetadata = parsePassportData(passportData);
const hashAlgorithm = passportMetadata.signedAttrHashFunction;
const { signatureAlgorithm, publicKeyDetails } = parseCertificateSimple(passportData.dsc);
let pubKey: any;
let signature: any;
let signatureAlgorithmFullName: string;
let n, k;
// const
// const { n, k } = getNAndK(`${signatureAlgorithm}_${hashFunction}_${curve || exponent}_${bits}` as any);
if (signatureAlgorithm === 'ecdsa') {
signatureAlgorithmFullName = `${signatureAlgorithm}_${hashAlgorithm}_${(publicKeyDetails as PublicKeyDetailsECDSA).curve}_${publicKeyDetails.bits}`;
@@ -205,44 +203,45 @@ export function generateCircuitInputsProve(
const dsc_modulus_y = splitToWords(BigInt(hexToDecimal(y)), n, k);
pubKey = [...dsc_modulus_x, ...dsc_modulus_y];
} else {
const { modulus, exponent } = (publicKeyDetails as PublicKeyDetailsRSA);
const { modulus, exponent } = publicKeyDetails as PublicKeyDetailsRSA;
signatureAlgorithmFullName = `${signatureAlgorithm}_${hashAlgorithm}_${exponent}_${publicKeyDetails.bits}`;
({ n, k } = getNAndK(signatureAlgorithmFullName as SignatureAlgorithm));
signature = splitToWords(BigInt(bytesToBigDecimal(encryptedDigest)), n, k);
pubKey = splitToWords(BigInt(hexToDecimal(modulus)), n, k);
}
console.log('signatureAlgorithmFullName', signatureAlgorithmFullName);
const formattedMrz = formatMrz(mrz);
const dg1Hash = hash(hashAlgorithm, formattedMrz);
const dg1HashOffset = findSubarrayIndex(eContent, dg1Hash);
console.log('\x1b[90m%s\x1b[0m', 'dg1HashOffset', dg1HashOffset);
assert(dg1HashOffset !== -1, `DG1 hash ${dg1Hash} not found in eContent`);
const eContentHash = hash(hashAlgorithm, eContent);
const eContentHashOffset = findSubarrayIndex(signedAttr, eContentHash);
console.log('\x1b[90m%s\x1b[0m', 'eContentHashOffset', eContentHashOffset);
assert(eContentHashOffset !== -1, `eContent hash ${eContentHash} not found in signedAttr`);
if (eContent.length > MAX_PADDED_ECONTENT_LEN[signatureAlgorithmFullName]) {
console.error(
`Data hashes too long (${eContent.length} bytes). Max length is ${MAX_PADDED_ECONTENT_LEN[signatureAlgorithmFullName]} bytes.`
`eContent too long (${eContent.length} bytes). Max length is ${MAX_PADDED_ECONTENT_LEN[signatureAlgorithmFullName]} bytes.`
);
throw new Error(
`This length of datagroups (${eContent.length} bytes) is currently unsupported. Please contact us so we add support!`
);
}
console.log('signatureAlgorithmFullName', signatureAlgorithmFullName);
const [eContentPadded, eContentLen] = shaPad(
const dg1PaddingFunction =
passportMetadata.dg1HashFunction === 'sha1' ||
passportMetadata.dg1HashFunction === 'sha224' ||
passportMetadata.dg1HashFunction === 'sha256'
? shaPad
: sha384_512Pad;
const [eContentPadded, eContentLen] = dg1PaddingFunction(
new Uint8Array(eContent),
MAX_PADDED_ECONTENT_LEN[signatureAlgorithmFullName]
MAX_PADDED_ECONTENT_LEN[passportMetadata.dg1HashFunction]
);
const [signedAttrPadded, signedAttrPaddedLen] = shaPad(
const eContentPaddingFunction =
passportMetadata.eContentHashFunction === 'sha1' ||
passportMetadata.eContentHashFunction === 'sha224' ||
passportMetadata.eContentHashFunction === 'sha256'
? shaPad
: sha384_512Pad;
const [signedAttrPadded, signedAttrPaddedLen] = eContentPaddingFunction(
new Uint8Array(signedAttr),
MAX_PADDED_SIGNED_ATTR_LEN[signatureAlgorithmFullName]
MAX_PADDED_SIGNED_ATTR_LEN[passportMetadata.eContentHashFunction]
);
const formattedMajority = majority.length === 1 ? `0${majority}` : majority;
@@ -257,17 +256,16 @@ export function generateCircuitInputsProve(
siblings: smt_siblings,
} = generateSMTProof(name_smt, name_leaf);
return {
selector_mode: formatInput(selector_mode),
dg1: formatInput(formattedMrz),
dg1_hash_offset: formatInput(dg1HashOffset),
dg1_hash_offset: formatInput(passportMetadata.dg1HashOffset),
dg2_hash: formatInput(formatDg2Hash(dg2Hash)),
eContent: Array.from(eContentPadded).map((x) => x.toString()),
eContent_padded_length: formatInput(eContentLen),
signed_attr: Array.from(signedAttrPadded).map((x) => x.toString()),
signed_attr_padded_length: formatInput(signedAttrPaddedLen),
signed_attr_econtent_hash_offset: formatInput(eContentHashOffset),
signed_attr_econtent_hash_offset: formatInput(passportMetadata.eContentHashOffset),
signature: signature,
pubKey: pubKey,
current_date: formatInput(getCurrentDateYYMMDD()),
@@ -282,7 +280,7 @@ export function generateCircuitInputsProve(
smt_leaf_value: formatInput(smt_leaf_value),
smt_siblings: formatInput(smt_siblings),
selector_ofac: formatInput(selector_ofac),
forbidden_countries_list: formatInput(formatCountriesList(forbidden_countries_list))
forbidden_countries_list: formatInput(formatCountriesList(forbidden_countries_list)),
};
}

View File

@@ -0,0 +1,45 @@
import { brutforceSignatureAlgorithmDsc } from "./brutForceDscSignature";
import { CertificateData } from "./certificate_parsing/dataStructure";
import { parseCertificateSimple } from "./certificate_parsing/parseCertificateSimple";
import { getCSCAFromSKI } from "./csca";
import { getCurveOrExponent } from "./parsePassportData";
export interface DscCertificateMetaData {
cscaFound: boolean;
cscaHashAlgorithm: string;
cscaSignatureAlgorithm: string;
cscaCurveOrExponent: string;
cscaSignatureAlgorithmBits: number;
cscaSaltLength: number;
}
export function parseDscCertificateData(dscCert: CertificateData): any {
let csca, parsedCsca, cscaHashAlgorithm, cscaSignatureAlgorithm, cscaCurveOrExponent, cscaSignatureAlgorithmBits, cscaSaltLength;
let cscaFound = false;
if (dscCert.authorityKeyIdentifier) {
try {
csca = getCSCAFromSKI(dscCert.authorityKeyIdentifier, true);
if (csca) {
parsedCsca = parseCertificateSimple(csca);
const details = brutforceSignatureAlgorithmDsc(dscCert, parsedCsca);
cscaFound = true;
cscaHashAlgorithm = details.hashAlgorithm;
cscaSignatureAlgorithm = details.signatureAlgorithm;
cscaCurveOrExponent = getCurveOrExponent(parsedCsca);
cscaSignatureAlgorithmBits = parseInt(parsedCsca.publicKeyDetails.bits);
cscaSaltLength = details.saltLength;
}
} catch (error) {
}
}
return {
cscaFound,
cscaHashAlgorithm,
cscaSignatureAlgorithm,
cscaCurveOrExponent,
cscaSignatureAlgorithmBits,
cscaSaltLength
}
}

View File

@@ -0,0 +1,154 @@
import { PassportData } from '../../../common/src/utils/types';
import { findSubarrayIndex, formatMrz, getHashLen, hash } from './utils';
import { parseCertificateSimple } from './certificate_parsing/parseCertificateSimple';
import {
CertificateData,
PublicKeyDetailsECDSA,
PublicKeyDetailsRSA,
PublicKeyDetailsRSAPSS,
} from './certificate_parsing/dataStructure';
import { hashAlgos } from '../constants/constants';
import { brutforceSignatureAlgorithm } from './brutForcePassportSignature';
import { DscCertificateMetaData, parseDscCertificateData } from './parseDscCertificateData';
export interface PassportMetadata {
dataGroups: string;
dg1HashFunction: string;
dg1HashOffset: number;
dgPaddingBytes: number;
eContentSize: number;
eContentHashFunction: string;
eContentHashOffset: number;
signedAttrSize: number;
signedAttrHashFunction: string;
signatureAlgorithm: string;
saltLength: number;
curveOrExponent: string;
signatureAlgorithmBits: number;
countryCode: string;
cscaFound: boolean;
cscaHashFunction: string;
cscaSignature: string;
cscaSaltLength: number;
cscaCurveOrExponent: string;
cscaSignatureAlgorithmBits: number;
dsc: string;
}
function findHashSizeOfEContent(eContent: number[], signedAttr: number[]) {
for (const hashFunction of hashAlgos) {
const hashValue = hash(hashFunction, eContent);
const hashOffset = findSubarrayIndex(signedAttr, hashValue as number[]);
if (hashOffset !== -1) {
return { hashFunction, offset: hashOffset };
}
}
return { hashFunction: 'unknown', offset: -1 };
}
function findDG1HashInEContent(
mrz: string,
eContent: number[]
): { hash: number[]; hashFunction: string; offset: number } | null {
const formattedMrz = formatMrz(mrz);
for (const hashFunction of hashAlgos) {
const hashValue = hash(hashFunction, formattedMrz);
const normalizedHash = (hashValue as number[]).map((byte) => (byte > 127 ? byte - 256 : byte));
const hashOffset = findSubarrayIndex(eContent, normalizedHash);
if (hashOffset !== -1) {
return { hash: hashValue as number[], hashFunction, offset: hashOffset };
}
}
return null;
}
function getDgPaddingBytes(passportData: PassportData, dg1HashFunction: string): number {
const formattedMrz = formatMrz(passportData.mrz);
const hashValue = hash(dg1HashFunction, formattedMrz);
const normalizedHash = (hashValue as number[]).map((byte) => (byte > 127 ? byte - 256 : byte));
const dg1HashOffset = findSubarrayIndex(passportData.eContent, normalizedHash);
const dg2Hash = passportData.dg2Hash;
const normalizedDg2Hash = (dg2Hash as number[]).map((byte) => (byte > 127 ? byte - 256 : byte));
const dg2HashOffset = findSubarrayIndex(passportData.eContent, normalizedDg2Hash);
return dg2HashOffset - dg1HashOffset - getHashLen(dg1HashFunction);
}
export function getCountryCodeFromMrz(mrz: string): string {
return mrz.substring(2, 5);
}
export function getCurveOrExponent(certData: CertificateData): string {
if (certData.signatureAlgorithm === 'rsapss' || certData.signatureAlgorithm === 'rsa') {
return (certData.publicKeyDetails as PublicKeyDetailsRSA).exponent;
}
return (certData.publicKeyDetails as PublicKeyDetailsECDSA).curve;
}
export function parsePassportData(passportData: PassportData): PassportMetadata {
const dg1HashInfo = passportData.mrz
? findDG1HashInEContent(passportData.mrz, passportData.eContent)
: null;
const dg1HashFunction = dg1HashInfo?.hashFunction || 'unknown';
const dg1HashOffset = dg1HashInfo?.offset || 0;
let dgPaddingBytes = -1;
try {
dgPaddingBytes = getDgPaddingBytes(passportData, dg1HashFunction);
} catch (error) {
console.error('Error getting DG padding bytes:', error);
}
const { hashFunction: eContentHashFunction, offset: eContentHashOffset } = findHashSizeOfEContent(
passportData.eContent,
passportData.signedAttr
);
const brutForcedPublicKeyDetails = brutforceSignatureAlgorithm(passportData);
let parsedDsc = null;
let dscSignatureAlgorithmBits = 0;
let brutForcedPublicKeyDetailsDsc: DscCertificateMetaData;
if (passportData.dsc) {
parsedDsc = parseCertificateSimple(passportData.dsc);
dscSignatureAlgorithmBits = parseInt(parsedDsc.publicKeyDetails?.bits || '0');
brutForcedPublicKeyDetailsDsc = parseDscCertificateData(parsedDsc)
}
return {
dataGroups:
passportData.dgPresents
?.toString()
.split(',')
.map((item) => item.replace('DG', ''))
.join(',') || 'None',
dg1HashFunction,
dg1HashOffset,
dgPaddingBytes,
eContentSize: passportData.eContent?.length || 0,
eContentHashFunction,
eContentHashOffset,
signedAttrSize: passportData.signedAttr?.length || 0,
signedAttrHashFunction: brutForcedPublicKeyDetails.hashAlgorithm,
signatureAlgorithm: brutForcedPublicKeyDetails.signatureAlgorithm,
saltLength: brutForcedPublicKeyDetails.saltLength,
curveOrExponent: parsedDsc ? getCurveOrExponent(parsedDsc) : 'unknown',
signatureAlgorithmBits: dscSignatureAlgorithmBits,
countryCode: passportData.mrz ? getCountryCodeFromMrz(passportData.mrz) : 'unknown',
cscaFound: brutForcedPublicKeyDetailsDsc.cscaFound,
cscaHashFunction: brutForcedPublicKeyDetailsDsc.cscaHashAlgorithm,
cscaSignature: brutForcedPublicKeyDetailsDsc.cscaSignatureAlgorithm,
cscaSaltLength: brutForcedPublicKeyDetailsDsc.cscaSaltLength,
cscaCurveOrExponent: brutForcedPublicKeyDetailsDsc.cscaCurveOrExponent,
cscaSignatureAlgorithmBits: brutForcedPublicKeyDetailsDsc.cscaSignatureAlgorithmBits,
dsc: passportData.dsc,
};
}

View File

@@ -1,15 +1,14 @@
import {
PUBKEY_TREE_DEPTH,
COMMITMENT_TREE_TRACKER_URL,
SignatureAlgorithmIndex,
} from '../constants/constants';
import { SignatureAlgorithmIndex } from '../constants/constants';
import { LeanIMT } from '@openpassport/zk-kit-lean-imt';
import axios from 'axios';
import { poseidon16, poseidon2, poseidon6, poseidon7 } from 'poseidon-lite';
import { poseidon16, poseidon2, poseidon7 } from 'poseidon-lite';
import { formatDg2Hash, getNAndK, getNAndKCSCA, hexToDecimal, splitToWords } from './utils';
import { flexiblePoseidon } from './poseidon';
import { parseCertificateSimple } from './certificate_parsing/parseCertificateSimple';
import { PublicKeyDetailsECDSA, PublicKeyDetailsRSA } from './certificate_parsing/dataStructure';
import {
PublicKeyDetailsECDSA,
PublicKeyDetailsRSA,
PublicKeyDetailsRSAPSS,
} from './certificate_parsing/dataStructure';
import { SignatureAlgorithm } from './types';
export function customHasher(pubKeyFormatted: string[]) {
@@ -30,9 +29,7 @@ export function customHasher(pubKeyFormatted: string[]) {
}
export function getLeaf(dsc: string): string {
const { signatureAlgorithm, hashAlgorithm, publicKeyDetails } = parseCertificateSimple(dsc);
const { signatureAlgorithm, publicKeyDetails, hashAlgorithm } = parseCertificateSimple(dsc);
if (signatureAlgorithm === 'ecdsa') {
const { x, y, curve, bits } = publicKeyDetails as PublicKeyDetailsECDSA;
@@ -62,9 +59,9 @@ export function getLeaf(dsc: string): string {
}
}
export function getLeafCSCA(dsc: string): string {
const { signatureAlgorithm, hashAlgorithm, publicKeyDetails } = parseCertificateSimple(dsc);
const { n, k } = getNAndKCSCA(signatureAlgorithm as any);
const { signatureAlgorithm, publicKeyDetails, hashAlgorithm } = parseCertificateSimple(dsc);
const { n, k } = getNAndKCSCA(signatureAlgorithm as any);
if (signatureAlgorithm === 'ecdsa') {
const { x, y, curve, bits } = publicKeyDetails as PublicKeyDetailsECDSA;
@@ -73,11 +70,20 @@ export function getLeafCSCA(dsc: string): string {
let qx = splitToWords(BigInt(hexToDecimal(x)), n, k);
let qy = splitToWords(BigInt(hexToDecimal(y)), n, k);
return customHasher([sigAlgIndex, ...qx, ...qy]);
} else {
} else if (signatureAlgorithm === 'rsa') {
const { modulus, bits, exponent } = publicKeyDetails as PublicKeyDetailsRSA;
const sigAlgKey = `${signatureAlgorithm}_${hashAlgorithm}_${exponent}_${bits}`;
const sigAlgIndex = SignatureAlgorithmIndex[sigAlgKey];
const pubkeyChunked = splitToWords(BigInt(hexToDecimal(modulus)), n, k);
return customHasher([sigAlgIndex, ...pubkeyChunked]);
if (sigAlgIndex == undefined) {
console.error(`\x1b[31mInvalid signature algorithm: ${sigAlgKey}\x1b[0m`);
throw new Error(`Invalid signature algorithm: ${sigAlgKey}`);
}
} else if (signatureAlgorithm === 'rsapss') {
const { modulus, bits, exponent, hashAlgorithm } = publicKeyDetails as PublicKeyDetailsRSAPSS;
const sigAlgKey = `${signatureAlgorithm}_${hashAlgorithm}_${exponent}_${bits}`;
const sigAlgIndex = SignatureAlgorithmIndex[sigAlgKey];
if (sigAlgIndex == undefined) {
console.error(`\x1b[31mInvalid signature algorithm: ${sigAlgKey}\x1b[0m`);
throw new Error(`Invalid signature algorithm: ${sigAlgKey}`);

View File

@@ -21,39 +21,42 @@ export function shaPad(prehash_prepad_m: Uint8Array, maxShaBytes: number): [Uint
return [prehash_prepad_m, messageLen];
}
export function sha384_512Pad(prehash_prepad_m: Uint8Array, maxShaBytes: number): [Uint8Array, number] {
export function sha384_512Pad(
prehash_prepad_m: Uint8Array,
maxShaBytes: number
): [Uint8Array, number] {
// Length in bits before padding
let length_bits = prehash_prepad_m.length * 8;
// For SHA-384, length is stored in 128 bits (16 bytes)
let length_in_bytes = int128toBytes(length_bits);
// Add the 1 bit (as a byte with value 128)
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, int8toBytes(2 ** 7));
// Add padding zeros until total length is congruent to 896 mod 1024
while ((prehash_prepad_m.length * 8 + length_in_bytes.length * 8) % 1024 !== 0) {
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, int8toBytes(0));
}
// Append the length
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, length_in_bytes);
// Verify padding is correct (multiple of 1024 bits)
assert((prehash_prepad_m.length * 8) % 1024 === 0, "Padding did not complete properly!");
assert((prehash_prepad_m.length * 8) % 1024 === 0, 'Padding did not complete properly!');
let messageLen = prehash_prepad_m.length;
// Pad to max length if needed
while (prehash_prepad_m.length < maxShaBytes) {
prehash_prepad_m = mergeUInt8Arrays(prehash_prepad_m, int128toBytes(0));
}
assert(
prehash_prepad_m.length === maxShaBytes,
`Padding to max length did not complete properly! Your padded message is ${prehash_prepad_m.length} long but max is ${maxShaBytes}!`
);
return [prehash_prepad_m, messageLen];
}
@@ -61,12 +64,12 @@ export function sha384_512Pad(prehash_prepad_m: Uint8Array, maxShaBytes: number)
function int128toBytes(x: number): Uint8Array {
const buffer = new ArrayBuffer(16);
const view = new DataView(buffer);
// Write high 64 bits
view.setBigUint64(0, BigInt(0), false);
// Write low 64 bits
view.setBigUint64(8, BigInt(x), false);
return new Uint8Array(buffer);
}

View File

@@ -34,7 +34,16 @@ export type SignatureAlgorithm =
| 'rsapss_sha512_3_4096'
| 'rsapss_sha512_3_2048'
| 'rsapss_sha384_3_4096'
| 'rsapss_sha384_3_3072' ;
| 'rsapss_sha384_3_3072'
| 'ecdsa_sha256_secp384r1_384'
| 'ecdsa_sha384_brainpoolP256r1_256'
| 'ecdsa_sha512_brainpoolP256r1_256'
| 'ecdsa_sha384_brainpoolP384r1_384'
| 'ecdsa_sha512_brainpoolP384r1_384'
| 'ecdsa_sha1_brainpoolP224r1_224'
| 'ecdsa_sha224_brainpoolP224r1_224'
| 'ecdsa_sha256_brainpoolP224r1_224'
| 'ecdsa_sha512_brainpoolP512r1_512'
export type Proof = {
proof: {

View File

@@ -1,7 +1,7 @@
import { LeanIMT } from '@openpassport/zk-kit-lean-imt';
import { sha256 } from 'js-sha256';
import { sha224, sha256 } from 'js-sha256';
import { sha1 } from 'js-sha1';
import { sha384, sha512_256 } from 'js-sha512';
import { sha384, sha512 } from 'js-sha512';
import { SMT } from '@openpassport/zk-kit-smt';
import forge from 'node-forge';
import {
@@ -37,7 +37,19 @@ export function getNAndK(sigAlg: SignatureAlgorithm) {
}
if (sigAlg.startsWith('ecdsa_')) {
return { n: n_dsc_ecdsa, k: k_dsc_ecdsa }; // 256/32 = 8
if (sigAlg.endsWith('224')) {
return { n: 32, k: 7 };
} else if (sigAlg.endsWith('256')) {
return { n: n_dsc_ecdsa, k: 4 };
} else if (sigAlg.endsWith('384')) {
return { n: n_dsc_ecdsa, k: 6 };
} else if (sigAlg.endsWith('512')) {
return { n: n_dsc_ecdsa, k: 8 };
} else if (sigAlg.endsWith('521')) {
return { n: n_dsc_ecdsa, k: 16 };
} else {
throw new Error('invalid key size');
}
}
if (sigAlg.startsWith('rsapss_')) {
@@ -77,7 +89,6 @@ export function formatDg2Hash(dg2Hash: number[]) {
export function formatAndConcatenateDataHashes(
dataHashes: [number, number[]][],
hashLen: number,
dg1HashOffset: number
) {
// concatenating dataHashes :
@@ -159,7 +170,7 @@ export function formatAndConcatenateDataHashes(
return concat;
}
export function assembleEContent(messageDigest: number[]) {
export function generateSignedAttr(messageDigest: number[]) {
const constructedEContent = [];
// Detailed description is in private file r&d.ts for now
@@ -229,7 +240,7 @@ export function hexToDecimal(hex: string): string {
}
// hash logic here because the one in utils.ts only works with node
export function hash(hashFunction: string, bytesArray: number[]): number[] {
export function hash(hashFunction: string, bytesArray: number[], format: string = 'bytes'): string | number[] {
const unsignedBytesArray = bytesArray.map((byte) => byte & 0xff);
let hashResult: string;
@@ -237,6 +248,9 @@ export function hash(hashFunction: string, bytesArray: number[]): number[] {
case 'sha1':
hashResult = sha1(unsignedBytesArray);
break;
case 'sha224':
hashResult = sha224(unsignedBytesArray);
break;
case 'sha256':
hashResult = sha256(unsignedBytesArray);
break;
@@ -244,13 +258,22 @@ export function hash(hashFunction: string, bytesArray: number[]): number[] {
hashResult = sha384(unsignedBytesArray);
break;
case 'sha512':
hashResult = sha512_256(unsignedBytesArray);
hashResult = sha512(unsignedBytesArray);
break;
default:
console.log('\x1b[31m%s\x1b[0m', `${hashFunction} not found in hash`); // Log in red
hashResult = sha256(unsignedBytesArray); // Default to sha256
}
return hexToSignedBytes(hashResult);
if (format === 'hex') {
return hashResult;
}
if (format === 'bytes') {
return hexToSignedBytes(hashResult);
}
if (format === 'binary') {
return forge.util.binary.raw.encode(new Uint8Array(hexToSignedBytes(hashResult)));
}
throw new Error(`Invalid format: ${format}`);
}
export function hexToSignedBytes(hexString: string): number[] {
@@ -312,6 +335,8 @@ export function getHashLen(hashFunction: string) {
switch (hashFunction) {
case 'sha1':
return 20;
case 'sha224':
return 28;
case 'sha256':
return 32;
case 'sha384':
@@ -423,9 +448,7 @@ export function findSubarrayIndex(arr: number[], subArr: number[]): number {
return -1;
}
return arr.findIndex((_, i) =>
subArr.every((val, j) => arr[i + j] === val)
);
return arr.findIndex((_, i) => subArr.every((val, j) => arr[i + j] === val));
}
export function extractRSFromSignature(signatureBytes: number[]): { r: string; s: string } {

View File

@@ -1,115 +1,47 @@
import { assert, expect } from 'chai';
import { describe, it } from 'mocha';
import { genMockPassportData } from '../src/utils/genMockPassportData';
import * as forge from 'node-forge';
import { PassportData, SignatureAlgorithm } from '../src/utils/types';
import { formatMrz, hash, arraysAreEqual, findSubarrayIndex } from '../src/utils/utils';
import * as asn1 from 'asn1js';
import { Certificate } from 'pkijs';
import elliptic from 'elliptic';
import { parseCertificateSimple } from '../src/utils/certificate_parsing/parseCertificateSimple';
import { getCurveForElliptic } from '../src/utils/certificate_parsing/curves';
import { PublicKeyDetailsECDSA, PublicKeyDetailsRSAPSS } from '../src/utils/certificate_parsing/dataStructure';
import { parsePassportData } from '../src/utils/parsePassportData';
const sigAlgs: SignatureAlgorithm[] = [
'rsa_sha1_65537_2048',
'rsa_sha256_65537_2048',
'rsapss_sha256_65537_2048',
'ecdsa_sha256_secp256r1_256',
'ecdsa_sha1_secp256r1_256',
// 'ecdsa_sha384_secp384r1_384',
const testCases = [
{ dgHashAlgo: 'sha1', eContentHashAlgo: 'sha1', sigAlg: 'rsa_sha1_65537_2048' },
{ dgHashAlgo: 'sha1', eContentHashAlgo: 'sha1', sigAlg: 'rsa_sha256_65537_2048' },
{ dgHashAlgo: 'sha256', eContentHashAlgo: 'sha256', sigAlg: 'rsapss_sha256_65537_2048' },
{ dgHashAlgo: 'sha256', eContentHashAlgo: 'sha256', sigAlg: 'ecdsa_sha256_secp256r1_256' },
{ dgHashAlgo: 'sha256', eContentHashAlgo: 'sha256', sigAlg: 'ecdsa_sha256_brainpoolP256r1_256' },
{ dgHashAlgo: 'sha1', eContentHashAlgo: 'sha1', sigAlg: 'ecdsa_sha1_secp256r1_256' },
];
describe('Mock Passport Data Generator', function () {
this.timeout(0);
sigAlgs.forEach((sigAlg) => {
testCases.forEach(({ dgHashAlgo, eContentHashAlgo, sigAlg }) => {
it(`should generate valid passport data for ${sigAlg}`, () => {
const passportData = genMockPassportData(sigAlg, 'FRA', '000101', '300101');
expect(passportData).to.exist;
expect(verify(passportData)).to.be.true;
const passportData = genMockPassportData(
dgHashAlgo,
eContentHashAlgo,
sigAlg as SignatureAlgorithm,
'FRA',
'000101',
'300101'
);
expect(verify(passportData, dgHashAlgo, eContentHashAlgo, sigAlg)).to.be.true;
});
});
});
function verify(passportData: PassportData): boolean {
const { mrz, dsc, eContent, signedAttr, encryptedDigest } = passportData;
const { signatureAlgorithm, hashAlgorithm, publicKeyDetails } = parseCertificateSimple(dsc);
const formattedMrz = formatMrz(mrz);
const mrzHash = hash(hashAlgorithm, formattedMrz);
const dg1HashOffset = findSubarrayIndex(eContent, mrzHash);
assert(dg1HashOffset !== -1, 'MRZ hash index not found in eContent');
console.error(
'\x1b[32m',
'signatureAlgorithm',
signatureAlgorithm,
' hashAlgorithm',
hashAlgorithm,
'eContent size',
eContent.length,
'signedAttr size',
signedAttr.length,
'\x1b[0m'
);
const concatHash = hash(hashAlgorithm, eContent);
assert(
arraysAreEqual(concatHash, signedAttr.slice(signedAttr.length - getHashLen(hashAlgorithm))),
'concatHash is not at the right place in signedAttr'
);
function verify(passportData: PassportData, dgHashAlgo: string, eContentHashAlgo: string, sigAlg: string): boolean {
const passportMetaData = parsePassportData(passportData);
// console.log('passportMetaData', passportMetaData);
if (signatureAlgorithm === 'ecdsa') {
const certBuffer = Buffer.from(
dsc.replace(/(-----(BEGIN|END) CERTIFICATE-----|\n)/g, ''),
'base64'
);
const asn1Data = asn1.fromBER(certBuffer);
const cert = new Certificate({ schema: asn1Data.result });
const publicKeyInfo = cert.subjectPublicKeyInfo;
const publicKeyBuffer = publicKeyInfo.subjectPublicKey.valueBlock.valueHexView;
const curveForElliptic = getCurveForElliptic((publicKeyDetails as PublicKeyDetailsECDSA).curve);
const ec = new elliptic.ec(curveForElliptic);
expect(passportMetaData.dg1HashFunction).to.equal(dgHashAlgo);
expect(passportMetaData.eContentHashFunction).to.equal(eContentHashAlgo);
const key = ec.keyFromPublic(publicKeyBuffer);
const md = forge.md[hashAlgorithm].create();
md.update(forge.util.binary.raw.encode(new Uint8Array(signedAttr)));
const msgHash = md.digest().toHex();
const signature_crypto = Buffer.from(encryptedDigest).toString('hex');
// regex to find the signature algorithm (ecdsa or rsa/rsapss) before first underscore
const signatureAlgorithm = sigAlg.match(/^([^_]+)/)?.[1];
return key.verify(msgHash, signature_crypto);
} else {
const cert = forge.pki.certificateFromPem(dsc);
const publicKey = cert.publicKey as forge.pki.rsa.PublicKey;
expect(passportMetaData.signatureAlgorithm).to.equal(signatureAlgorithm);
const md = forge.md[hashAlgorithm].create();
md.update(forge.util.binary.raw.encode(new Uint8Array(signedAttr)));
const signature = Buffer.from(encryptedDigest).toString('binary');
if (signatureAlgorithm === 'rsapss') {
const pss = forge.pss.create({
md: forge.md[hashAlgorithm].create(),
mgf: forge.mgf.mgf1.create(forge.md[hashAlgorithm].create()),
saltLength: parseInt((publicKeyDetails as PublicKeyDetailsRSAPSS).saltLength),
});
return publicKey.verify(md.digest().bytes(), signature, pss);
} else {
return publicKey.verify(md.digest().bytes(), signature);
}
}
return true;
}
function getHashLen(hashAlgorithm: string): number {
if (hashAlgorithm === 'sha1') {
return 20;
} else if (hashAlgorithm === 'sha256') {
return 32;
} else if (hashAlgorithm === 'sha384') {
return 48;
} else if (hashAlgorithm === 'sha512') {
return 64;
} else {
throw new Error('Unsupported hash algorithm');
}
}

View File

@@ -1610,10 +1610,10 @@ __metadata:
languageName: node
linkType: hard
"js-sha256@npm:^0.10.1":
version: 0.10.1
resolution: "js-sha256@npm:0.10.1"
checksum: 10c0/c63119f7c7f8afc24bfa24c1a6b51147c3b562316b6341a375a1cef88569340ec0dbf2cda429ecf472cabfbae47a0b93a0cb82b8730883de066593c3f816c53b
"js-sha256@npm:^0.11.0":
version: 0.11.0
resolution: "js-sha256@npm:0.11.0"
checksum: 10c0/90980fe01ca01fbd166751fb16c4caa09c1ab997e8bf77c0764cc05c772c6044946f4c1b3bad266ce78357280d2131d3dc0cf2dd7646e78272996bd4d590aa4f
languageName: node
linkType: hard
@@ -2086,7 +2086,7 @@ __metadata:
elliptic: "npm:^6.5.5"
fs: "npm:^0.0.1-security"
js-sha1: "npm:^0.7.0"
js-sha256: "npm:^0.10.1"
js-sha256: "npm:^0.11.0"
js-sha512: "npm:^0.9.0"
json-to-ts: "npm:^2.1.0"
jsrsasign: "npm:^11.1.0"