-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpock.js
99 lines (80 loc) · 3.45 KB
/
pock.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
(function () {
const SERIAL_NUMBER = 1;
const DATE = '500101000000Z';
const CN_RDN_VALUE = '-'.repeat(20) + 'PROOF OF COMPROMISED KEY' + '-'.repeat(20);
function getChallengeCertificateSubject () {
return `/CN=${CN_RDN_VALUE}`;
}
function isSelfSigned (certificate) {
const publicKey = certificate.getPublicKey();
return certificate.getSubjectHex() == certificate.getIssuerHex() &&
certificate.verifySignature(publicKey);
}
function verifyCertificateFields (certificate) {
const basicConstraints = certificate.getExtBasicConstraints();
return parseInt(certificate.getSerialNumberHex(), 16) == SERIAL_NUMBER &&
certificate.getNotBefore() == DATE &&
certificate.getNotBefore() == certificate.getNotAfter() &&
certificate.getSubjectString() == getChallengeCertificateSubject() &&
certificate.aExtInfo.length == 1 &&
basicConstraints && $.isEmptyObject(basicConstraints);
}
function getSignatureAlgorithmNameForKey (key) {
switch (key.constructor) {
case KJUR.crypto.ECDSA:
switch (key.getShortNISTPCurveName()) {
case 'P-256':
return 'SHA256withECDSA';
case 'P-384':
return 'SHA384withECDSA';
default:
throw 'Unsupported ECDSA curve';
}
case RSAKey:
return 'SHA256withRSA';
default:
throw 'Unsupported key type: ' + key.constructor;
}
}
window.getPemThumbprint = function(pem) {
const hex = pemtohex(pem);
return KJUR.crypto.Util.hashHex(hex, 'sha256');
}
window.readCertificatePem = function (certificatePem) {
const certificate = new X509();
certificate.readCertPEM(certificatePem);
return certificate;
}
window.createProofOfCompromisedKey = function (privateKeyPem) {
const key = KEYUTIL.getKey(privateKeyPem);
const dn = getChallengeCertificateSubject();
const sigAlgName = getSignatureAlgorithmNameForKey(key);
const challengeCertificatePem = KJUR.asn1.x509.X509Util.newCertPEM({
serial: {int: SERIAL_NUMBER},
sigalg: {name: sigAlgName},
issuer: {str: dn},
subject: {str: dn},
notbefore: {str: DATE},
notafter: {str: DATE},
ext: [
{basicConstraints: {cA: false, critical: true}}
],
sbjpubkey: privateKeyPem,
cakey: key
});
return challengeCertificatePem;
};
window.verifyProofOfCompromisedKey = function (compromisedCertificatePem, challengeCertificatePem) {
const compromisedCertificate = compromisedCertificatePem ? readCertificatePem(compromisedCertificatePem) : null;
const challengeCertificate = readCertificatePem(challengeCertificatePem);
if (!verifyCertificateFields(challengeCertificate)) {
throw 'PoCK does not contain the expected certificate field values';
}
if (!isSelfSigned (challengeCertificate)) {
throw 'PoCK is not self-signed';
}
if (compromisedCertificate && compromisedCertificate.getPublicKeyHex() != challengeCertificate.getPublicKeyHex()) {
throw 'Compromised certificate and PoCK public keys do not match';
}
};
})();