Skip to content

Commit 53945e7

Browse files
phoddiemkellner
authored andcommitted
validate certificate dates
1 parent d265a83 commit 53945e7

File tree

4 files changed

+66
-10
lines changed

4 files changed

+66
-10
lines changed

modules/crypt/digest/modCrypt.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,10 @@ void resolveBuffer(xsMachine *the, xsSlot *slot, uint8_t **data, uint32_t *count
11291129
byteOffset = xsmcToInteger(tmp);
11301130

11311131
xsmcGet(tmp, *slot, xsID_buffer);
1132-
*data = byteOffset + (uint8_t *)xsmcToArrayBuffer(tmp);
1132+
if (xsmcIsInstanceOf(tmp, xsArrayBufferPrototype))
1133+
*data = byteOffset + (uint8_t *)xsmcToArrayBuffer(tmp);
1134+
else
1135+
*data = byteOffset + (uint8_t *)xsmcGetHostData(tmp);
11331136
}
11341137
}
11351138
else { // host buffer

modules/crypt/etc/x509.js

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ let X509 = {
5454
let tbs = {};
5555
let ber = new BER(buf);
5656
if (ber.getTag() != 0x30)
57-
throw new Error("x509: malfromed TBS");
57+
throw new Error("x509: malformed TBS");
5858
ber.getLength();
5959
if (ber.peek() & 0x80) {
6060
ber.skip(1);
@@ -63,12 +63,21 @@ let X509 = {
6363
tbs.serialNumber = ber.next();
6464
tbs.signature = ber.next();
6565
tbs.issuer = ber.next();
66-
tbs.validity = ber.next();
66+
67+
let validity = new BER(ber.next());
68+
if (validity.getTag() != 0x30)
69+
throw new Error("x509: malformed TBS");
70+
validity.getLength();
71+
let from = validity.next();
72+
let to = validity.next();
73+
from = parseDate(String.fromArrayBuffer(from.buffer.slice(from.byteOffset + 2, from.byteOffset + 2 + from.length - 2)));
74+
to = parseDate(String.fromArrayBuffer(to.buffer.slice(to.byteOffset + 2, to.byteOffset + 2 + to.length - 2)));
75+
tbs.validity = {from, to};
6776
tbs.subject = ber.next();
6877
tbs.subjectPublicKeyInfo = ber.next();
6978
return tbs;
7079
},
71-
getSPK(buf) {
80+
getSPK(buf) { // Subject Public Key Info
7281
let spki = this._decodeSPKI(buf);
7382
if (!spki)
7483
throw new Error("x509: no SPKI");
@@ -144,7 +153,27 @@ let X509 = {
144153
_decodeSPKI(buf) @ "xs_x509_decodeSPKI",
145154
decodeExtension(buf, extid) @ "xs_x509_decodeExtension",
146155
};
147-
148156
Object.freeze(X509);
149157

158+
function parseDate(date) {
159+
if (!date.endsWith("Z"))
160+
throw new Error("unexpected timezone");
161+
162+
let parts = [];
163+
if (13 === date.length) {
164+
for (let i = 0; (i + 1) < date.length; i += 2)
165+
parts.push(parseInt(date.substring(i, i + 2)));
166+
parts[0] += (parts[0] < 50) ? 2000 : 1900;
167+
}
168+
else if (15 === date.length) {
169+
parse.push(parseInt(date.substring(0, 4)));
170+
for (let i = 4; (i + 1) < date.length; i += 2)
171+
parts.push(parseInt(date.substring(i, i + 2)));
172+
}
173+
else
174+
throw new Error("unexpected date");
175+
parts[1] -= 1;
176+
return Date.UTC.apply(null, parts);
177+
}
178+
150179
export default X509;

modules/crypt/ssl/ssl_cert.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,28 @@ class CertificateManager {
9494
var i = this.getIndex(fname, target);
9595
if (i < 0)
9696
return; // undefined
97-
return X509.decodeSPKI(getResource("ca" + i + ".der"));
97+
let data = getResource("ca" + i + ".der");
98+
let validity = X509.decodeTBS(X509.decode(new Uint8Array(data)).tbs).validity;
99+
let now = Date.now();
100+
if (!((validity.from < now) && (now < validity.to))) {
101+
trace("date validation failed on certificate resource\n");
102+
return;
103+
}
104+
return X509.decodeSPKI(data);
98105
};
99106
verify(certs) {
100-
let length = certs.length - 1;
107+
let length = certs.length - 1, x509, validity, now = Date.now();
101108

102109
// this approach calls decodeSPKI once more than necessary in favor of minimizing memory use
103110
for (let i = 0; i < length; i++) {
104-
if (!this._verify(X509.decodeSPKI(certs[i + 1]), X509.decode(certs[i])))
111+
x509 = X509.decode(certs[i]);
112+
validity = X509.decodeTBS(x509.tbs).validity;
113+
if (!((validity.from < now) && (now < validity.to))) {
114+
trace("date validation failed on received certificate\n");
115+
return false;
116+
}
117+
118+
if (!this._verify(X509.decodeSPKI(certs[i + 1]), x509))
105119
return false;
106120

107121
let aki = X509.decodeAKI(certs[i + 1]);
@@ -120,7 +134,11 @@ class CertificateManager {
120134
// else fall thru
121135
}
122136

123-
let x509 = X509.decode(certs[length]);
137+
x509 = X509.decode(certs[length]);
138+
validity = X509.decodeTBS(x509.tbs).validity;
139+
if (!((validity.from < now) && (now < validity.to)))
140+
throw new Error("date validation failed");
141+
124142
let spki = this.findCert("ca.ski", X509.decodeAKI(certs[length]));
125143
if (spki && this._verify(spki, x509))
126144
return true;
@@ -186,6 +204,10 @@ class CertificateManager {
186204
return (new pk(spki, false, [] /* any oid */)).verify(H, sig);
187205
};
188206
register(cert) {
207+
let validity = X509.decodeTBS(X509.decode(new Uint8Array(cert)).tbs).validity, now = Date.now();
208+
if (!((validity.from < now) && (now < validity.to)))
209+
throw new Error("date validation failed");
210+
189211
this.registeredCerts.push(cert);
190212
};
191213
getDH() {

modules/crypt/ssl/ssl_session.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@ class SSLSession {
293293
trace("ALERT! (" + this.alert.level + ", " + htis.alert.description + "\n");
294294
return;
295295
}
296+
if (undefined === this.traceLevel)
297+
return;
298+
296299
let algo = "";
297300
switch (this.chosenCipher.keyExchangeAlgorithm) {
298301
case RSA: algo = "RSA"; break;
@@ -321,7 +324,6 @@ class SSLSession {
321324
case SHA384: hash = "SHA384"; break;
322325
}
323326
trace("FINISHED: " + algo + "-" + enc + "-" + mode + "-" + hash + "\n");
324-
// debugger;
325327
}
326328
};
327329

0 commit comments

Comments
 (0)