node-forge 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +83 -0
- package/dist/forge.all.min.js +1 -1
- package/dist/forge.min.js +1 -1
- package/lib/asn1.js +29 -3
- package/lib/log.js +5 -8
- package/lib/oids.js +6 -0
- package/lib/rsa.js +81 -3
- package/lib/x509.js +122 -217
- package/package.json +1 -1
package/lib/asn1.js
CHANGED
|
@@ -411,6 +411,8 @@ var _getValueLength = function(bytes, remaining) {
|
|
|
411
411
|
* @param [options] object with options or boolean strict flag
|
|
412
412
|
* [strict] true to be strict when checking value lengths, false to
|
|
413
413
|
* allow truncated values (default: true).
|
|
414
|
+
* [parseAllBytes] true to ensure all bytes are parsed
|
|
415
|
+
* (default: true)
|
|
414
416
|
* [decodeBitStrings] true to attempt to decode the content of
|
|
415
417
|
* BIT STRINGs (not OCTET STRINGs) using strict mode. Note that
|
|
416
418
|
* without schema support to understand the data context this can
|
|
@@ -418,24 +420,31 @@ var _getValueLength = function(bytes, remaining) {
|
|
|
418
420
|
* flag will be deprecated or removed as soon as schema support is
|
|
419
421
|
* available. (default: true)
|
|
420
422
|
*
|
|
423
|
+
* @throws Will throw an error for various malformed input conditions.
|
|
424
|
+
*
|
|
421
425
|
* @return the parsed asn1 object.
|
|
422
426
|
*/
|
|
423
427
|
asn1.fromDer = function(bytes, options) {
|
|
424
428
|
if(options === undefined) {
|
|
425
429
|
options = {
|
|
426
430
|
strict: true,
|
|
431
|
+
parseAllBytes: true,
|
|
427
432
|
decodeBitStrings: true
|
|
428
433
|
};
|
|
429
434
|
}
|
|
430
435
|
if(typeof options === 'boolean') {
|
|
431
436
|
options = {
|
|
432
437
|
strict: options,
|
|
438
|
+
parseAllBytes: true,
|
|
433
439
|
decodeBitStrings: true
|
|
434
440
|
};
|
|
435
441
|
}
|
|
436
442
|
if(!('strict' in options)) {
|
|
437
443
|
options.strict = true;
|
|
438
444
|
}
|
|
445
|
+
if(!('parseAllBytes' in options)) {
|
|
446
|
+
options.parseAllBytes = true;
|
|
447
|
+
}
|
|
439
448
|
if(!('decodeBitStrings' in options)) {
|
|
440
449
|
options.decodeBitStrings = true;
|
|
441
450
|
}
|
|
@@ -445,7 +454,15 @@ asn1.fromDer = function(bytes, options) {
|
|
|
445
454
|
bytes = forge.util.createBuffer(bytes);
|
|
446
455
|
}
|
|
447
456
|
|
|
448
|
-
|
|
457
|
+
var byteCount = bytes.length();
|
|
458
|
+
var value = _fromDer(bytes, bytes.length(), 0, options);
|
|
459
|
+
if(options.parseAllBytes && bytes.length() !== 0) {
|
|
460
|
+
var error = new Error('Unparsed DER bytes remain after ASN.1 parsing.');
|
|
461
|
+
error.byteCount = byteCount;
|
|
462
|
+
error.remaining = bytes.length();
|
|
463
|
+
throw error;
|
|
464
|
+
}
|
|
465
|
+
return value;
|
|
449
466
|
};
|
|
450
467
|
|
|
451
468
|
/**
|
|
@@ -566,7 +583,6 @@ function _fromDer(bytes, remaining, depth, options) {
|
|
|
566
583
|
start = bytes.length();
|
|
567
584
|
var subOptions = {
|
|
568
585
|
// enforce strict mode to avoid parsing ASN.1 from plain data
|
|
569
|
-
verbose: options.verbose,
|
|
570
586
|
strict: true,
|
|
571
587
|
decodeBitStrings: true
|
|
572
588
|
};
|
|
@@ -615,6 +631,7 @@ function _fromDer(bytes, remaining, depth, options) {
|
|
|
615
631
|
}
|
|
616
632
|
} else {
|
|
617
633
|
value = bytes.getBytes(length);
|
|
634
|
+
remaining -= length;
|
|
618
635
|
}
|
|
619
636
|
}
|
|
620
637
|
|
|
@@ -1391,7 +1408,16 @@ asn1.prettyPrint = function(obj, level, indentation) {
|
|
|
1391
1408
|
}
|
|
1392
1409
|
rval += '0x' + forge.util.bytesToHex(obj.value);
|
|
1393
1410
|
} else if(obj.type === asn1.Type.UTF8) {
|
|
1394
|
-
|
|
1411
|
+
try {
|
|
1412
|
+
rval += forge.util.decodeUtf8(obj.value);
|
|
1413
|
+
} catch(e) {
|
|
1414
|
+
if(e.message === 'URI malformed') {
|
|
1415
|
+
rval +=
|
|
1416
|
+
'0x' + forge.util.bytesToHex(obj.value) + ' (malformed UTF8)';
|
|
1417
|
+
} else {
|
|
1418
|
+
throw e;
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1395
1421
|
} else if(obj.type === asn1.Type.PRINTABLESTRING ||
|
|
1396
1422
|
obj.type === asn1.Type.IA5String) {
|
|
1397
1423
|
rval += obj.value;
|
package/lib/log.js
CHANGED
|
@@ -286,7 +286,7 @@ if(typeof(console) !== 'undefined' && 'log' in console) {
|
|
|
286
286
|
}
|
|
287
287
|
|
|
288
288
|
/*
|
|
289
|
-
* Check for logging control query vars.
|
|
289
|
+
* Check for logging control query vars in current URL.
|
|
290
290
|
*
|
|
291
291
|
* console.level=<level-name>
|
|
292
292
|
* Set's the console log level by name. Useful to override defaults and
|
|
@@ -297,13 +297,10 @@ if(typeof(console) !== 'undefined' && 'log' in console) {
|
|
|
297
297
|
* after console.level is processed. Useful to force a level of verbosity
|
|
298
298
|
* that could otherwise be limited by a user config.
|
|
299
299
|
*/
|
|
300
|
-
if(sConsoleLogger !== null
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
} else {
|
|
305
|
-
query = new URLSearchParams();
|
|
306
|
-
}
|
|
300
|
+
if(sConsoleLogger !== null &&
|
|
301
|
+
typeof window !== 'undefined' && window.location
|
|
302
|
+
) {
|
|
303
|
+
var query = new URL(window.location.href).searchParams;
|
|
307
304
|
if(query.has('console.level')) {
|
|
308
305
|
// set with last value
|
|
309
306
|
forge.log.setLevel(
|
package/lib/oids.js
CHANGED
|
@@ -42,9 +42,15 @@ _IN('1.2.840.10040.4.3', 'dsa-with-sha1');
|
|
|
42
42
|
_IN('1.3.14.3.2.7', 'desCBC');
|
|
43
43
|
|
|
44
44
|
_IN('1.3.14.3.2.26', 'sha1');
|
|
45
|
+
// Deprecated equivalent of sha1WithRSAEncryption
|
|
46
|
+
_IN('1.3.14.3.2.29', 'sha1WithRSASignature');
|
|
45
47
|
_IN('2.16.840.1.101.3.4.2.1', 'sha256');
|
|
46
48
|
_IN('2.16.840.1.101.3.4.2.2', 'sha384');
|
|
47
49
|
_IN('2.16.840.1.101.3.4.2.3', 'sha512');
|
|
50
|
+
_IN('2.16.840.1.101.3.4.2.4', 'sha224');
|
|
51
|
+
_IN('2.16.840.1.101.3.4.2.5', 'sha512-224');
|
|
52
|
+
_IN('2.16.840.1.101.3.4.2.6', 'sha512-256');
|
|
53
|
+
_IN('1.2.840.113549.2.2', 'md2');
|
|
48
54
|
_IN('1.2.840.113549.2.5', 'md5');
|
|
49
55
|
|
|
50
56
|
// pkcs#7 content types
|
package/lib/rsa.js
CHANGED
|
@@ -264,6 +264,40 @@ var publicKeyValidator = forge.pki.rsa.publicKeyValidator = {
|
|
|
264
264
|
}]
|
|
265
265
|
};
|
|
266
266
|
|
|
267
|
+
// validator for a DigestInfo structure
|
|
268
|
+
var digestInfoValidator = {
|
|
269
|
+
name: 'DigestInfo',
|
|
270
|
+
tagClass: asn1.Class.UNIVERSAL,
|
|
271
|
+
type: asn1.Type.SEQUENCE,
|
|
272
|
+
constructed: true,
|
|
273
|
+
value: [{
|
|
274
|
+
name: 'DigestInfo.DigestAlgorithm',
|
|
275
|
+
tagClass: asn1.Class.UNIVERSAL,
|
|
276
|
+
type: asn1.Type.SEQUENCE,
|
|
277
|
+
constructed: true,
|
|
278
|
+
value: [{
|
|
279
|
+
name: 'DigestInfo.DigestAlgorithm.algorithmIdentifier',
|
|
280
|
+
tagClass: asn1.Class.UNIVERSAL,
|
|
281
|
+
type: asn1.Type.OID,
|
|
282
|
+
constructed: false,
|
|
283
|
+
capture: 'algorithmIdentifier'
|
|
284
|
+
}, {
|
|
285
|
+
// NULL paramters
|
|
286
|
+
name: 'DigestInfo.DigestAlgorithm.parameters',
|
|
287
|
+
tagClass: asn1.Class.UNIVERSAL,
|
|
288
|
+
type: asn1.Type.NULL,
|
|
289
|
+
constructed: false
|
|
290
|
+
}]
|
|
291
|
+
}, {
|
|
292
|
+
// digest
|
|
293
|
+
name: 'DigestInfo.digest',
|
|
294
|
+
tagClass: asn1.Class.UNIVERSAL,
|
|
295
|
+
type: asn1.Type.OCTETSTRING,
|
|
296
|
+
constructed: false,
|
|
297
|
+
capture: 'digest'
|
|
298
|
+
}]
|
|
299
|
+
};
|
|
300
|
+
|
|
267
301
|
/**
|
|
268
302
|
* Wrap digest in DigestInfo object.
|
|
269
303
|
*
|
|
@@ -1092,15 +1126,27 @@ pki.setRsaPublicKey = pki.rsa.setPublicKey = function(n, e) {
|
|
|
1092
1126
|
* a Forge PSS object for RSASSA-PSS,
|
|
1093
1127
|
* 'NONE' or null for none, DigestInfo will not be expected, but
|
|
1094
1128
|
* PKCS#1 v1.5 padding will still be used.
|
|
1129
|
+
* @param options optional verify options
|
|
1130
|
+
* _parseAllDigestBytes testing flag to control parsing of all
|
|
1131
|
+
* digest bytes. Unsupported and not for general usage.
|
|
1132
|
+
* (default: true)
|
|
1095
1133
|
*
|
|
1096
1134
|
* @return true if the signature was verified, false if not.
|
|
1097
1135
|
*/
|
|
1098
|
-
key.verify = function(digest, signature, scheme) {
|
|
1136
|
+
key.verify = function(digest, signature, scheme, options) {
|
|
1099
1137
|
if(typeof scheme === 'string') {
|
|
1100
1138
|
scheme = scheme.toUpperCase();
|
|
1101
1139
|
} else if(scheme === undefined) {
|
|
1102
1140
|
scheme = 'RSASSA-PKCS1-V1_5';
|
|
1103
1141
|
}
|
|
1142
|
+
if(options === undefined) {
|
|
1143
|
+
options = {
|
|
1144
|
+
_parseAllDigestBytes: true
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
if(!('_parseAllDigestBytes' in options)) {
|
|
1148
|
+
options._parseAllDigestBytes = true;
|
|
1149
|
+
}
|
|
1104
1150
|
|
|
1105
1151
|
if(scheme === 'RSASSA-PKCS1-V1_5') {
|
|
1106
1152
|
scheme = {
|
|
@@ -1108,9 +1154,41 @@ pki.setRsaPublicKey = pki.rsa.setPublicKey = function(n, e) {
|
|
|
1108
1154
|
// remove padding
|
|
1109
1155
|
d = _decodePkcs1_v1_5(d, key, true);
|
|
1110
1156
|
// d is ASN.1 BER-encoded DigestInfo
|
|
1111
|
-
var obj = asn1.fromDer(d
|
|
1157
|
+
var obj = asn1.fromDer(d, {
|
|
1158
|
+
parseAllBytes: options._parseAllDigestBytes
|
|
1159
|
+
});
|
|
1160
|
+
|
|
1161
|
+
// validate DigestInfo
|
|
1162
|
+
var capture = {};
|
|
1163
|
+
var errors = [];
|
|
1164
|
+
if(!asn1.validate(obj, digestInfoValidator, capture, errors)) {
|
|
1165
|
+
var error = new Error(
|
|
1166
|
+
'ASN.1 object does not contain a valid RSASSA-PKCS1-v1_5 ' +
|
|
1167
|
+
'DigestInfo value.');
|
|
1168
|
+
error.errors = errors;
|
|
1169
|
+
throw error;
|
|
1170
|
+
}
|
|
1171
|
+
// check hash algorithm identifier
|
|
1172
|
+
// see PKCS1-v1-5DigestAlgorithms in RFC 8017
|
|
1173
|
+
// FIXME: add support to vaidator for strict value choices
|
|
1174
|
+
var oid = asn1.derToOid(capture.algorithmIdentifier);
|
|
1175
|
+
if(!(oid === forge.oids.md2 ||
|
|
1176
|
+
oid === forge.oids.md5 ||
|
|
1177
|
+
oid === forge.oids.sha1 ||
|
|
1178
|
+
oid === forge.oids.sha224 ||
|
|
1179
|
+
oid === forge.oids.sha256 ||
|
|
1180
|
+
oid === forge.oids.sha384 ||
|
|
1181
|
+
oid === forge.oids.sha512 ||
|
|
1182
|
+
oid === forge.oids['sha512-224'] ||
|
|
1183
|
+
oid === forge.oids['sha512-256'])) {
|
|
1184
|
+
var error = new Error(
|
|
1185
|
+
'Unknown RSASSA-PKCS1-v1_5 DigestAlgorithm identifier.');
|
|
1186
|
+
error.oid = oid;
|
|
1187
|
+
throw error;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1112
1190
|
// compare the given digest to the decrypted one
|
|
1113
|
-
return digest ===
|
|
1191
|
+
return digest === capture.digest;
|
|
1114
1192
|
}
|
|
1115
1193
|
};
|
|
1116
1194
|
} else if(scheme === 'NONE' || scheme === 'NULL' || scheme === null) {
|
package/lib/x509.js
CHANGED
|
@@ -689,6 +689,101 @@ var _readSignatureParameters = function(oid, obj, fillDefaults) {
|
|
|
689
689
|
return params;
|
|
690
690
|
};
|
|
691
691
|
|
|
692
|
+
/**
|
|
693
|
+
* Create signature digest for OID.
|
|
694
|
+
*
|
|
695
|
+
* @param options
|
|
696
|
+
* signatureOid: the OID specifying the signature algorithm.
|
|
697
|
+
* type: a human readable type for error messages
|
|
698
|
+
* @return a created md instance. throws if unknown oid.
|
|
699
|
+
*/
|
|
700
|
+
var _createSignatureDigest = function(options) {
|
|
701
|
+
switch(oids[options.signatureOid]) {
|
|
702
|
+
case 'sha1WithRSAEncryption':
|
|
703
|
+
// deprecated alias
|
|
704
|
+
case 'sha1WithRSASignature':
|
|
705
|
+
return forge.md.sha1.create();
|
|
706
|
+
case 'md5WithRSAEncryption':
|
|
707
|
+
return forge.md.md5.create();
|
|
708
|
+
case 'sha256WithRSAEncryption':
|
|
709
|
+
return forge.md.sha256.create();
|
|
710
|
+
case 'sha384WithRSAEncryption':
|
|
711
|
+
return forge.md.sha384.create();
|
|
712
|
+
case 'sha512WithRSAEncryption':
|
|
713
|
+
return forge.md.sha512.create();
|
|
714
|
+
case 'RSASSA-PSS':
|
|
715
|
+
return forge.md.sha256.create();
|
|
716
|
+
default:
|
|
717
|
+
var error = new Error(
|
|
718
|
+
'Could not compute ' + options.type + ' digest. ' +
|
|
719
|
+
'Unknown signature OID.');
|
|
720
|
+
error.signatureOid = options.signatureOid;
|
|
721
|
+
throw error;
|
|
722
|
+
}
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Verify signature on certificate or CSR.
|
|
727
|
+
*
|
|
728
|
+
* @param options:
|
|
729
|
+
* certificate the certificate or CSR to verify.
|
|
730
|
+
* md the signature digest.
|
|
731
|
+
* signature the signature
|
|
732
|
+
* @return a created md instance. throws if unknown oid.
|
|
733
|
+
*/
|
|
734
|
+
var _verifySignature = function(options) {
|
|
735
|
+
var cert = options.certificate;
|
|
736
|
+
var scheme;
|
|
737
|
+
|
|
738
|
+
switch(cert.signatureOid) {
|
|
739
|
+
case oids.sha1WithRSAEncryption:
|
|
740
|
+
// deprecated alias
|
|
741
|
+
case oids.sha1WithRSASignature:
|
|
742
|
+
/* use PKCS#1 v1.5 padding scheme */
|
|
743
|
+
break;
|
|
744
|
+
case oids['RSASSA-PSS']:
|
|
745
|
+
var hash, mgf;
|
|
746
|
+
|
|
747
|
+
/* initialize mgf */
|
|
748
|
+
hash = oids[cert.signatureParameters.mgf.hash.algorithmOid];
|
|
749
|
+
if(hash === undefined || forge.md[hash] === undefined) {
|
|
750
|
+
var error = new Error('Unsupported MGF hash function.');
|
|
751
|
+
error.oid = cert.signatureParameters.mgf.hash.algorithmOid;
|
|
752
|
+
error.name = hash;
|
|
753
|
+
throw error;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
mgf = oids[cert.signatureParameters.mgf.algorithmOid];
|
|
757
|
+
if(mgf === undefined || forge.mgf[mgf] === undefined) {
|
|
758
|
+
var error = new Error('Unsupported MGF function.');
|
|
759
|
+
error.oid = cert.signatureParameters.mgf.algorithmOid;
|
|
760
|
+
error.name = mgf;
|
|
761
|
+
throw error;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
mgf = forge.mgf[mgf].create(forge.md[hash].create());
|
|
765
|
+
|
|
766
|
+
/* initialize hash function */
|
|
767
|
+
hash = oids[cert.signatureParameters.hash.algorithmOid];
|
|
768
|
+
if(hash === undefined || forge.md[hash] === undefined) {
|
|
769
|
+
var error = new Error('Unsupported RSASSA-PSS hash function.');
|
|
770
|
+
error.oid = cert.signatureParameters.hash.algorithmOid;
|
|
771
|
+
error.name = hash;
|
|
772
|
+
throw error;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
scheme = forge.pss.create(
|
|
776
|
+
forge.md[hash].create(), mgf, cert.signatureParameters.saltLength
|
|
777
|
+
);
|
|
778
|
+
break;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// verify signature on cert using public key
|
|
782
|
+
return cert.publicKey.verify(
|
|
783
|
+
options.md.digest().getBytes(), options.signature, scheme
|
|
784
|
+
);
|
|
785
|
+
};
|
|
786
|
+
|
|
692
787
|
/**
|
|
693
788
|
* Converts an X.509 certificate from PEM format.
|
|
694
789
|
*
|
|
@@ -1069,43 +1164,18 @@ pki.createCertificate = function() {
|
|
|
1069
1164
|
'The parent certificate did not issue the given child ' +
|
|
1070
1165
|
'certificate; the child certificate\'s issuer does not match the ' +
|
|
1071
1166
|
'parent\'s subject.');
|
|
1072
|
-
error.expectedIssuer =
|
|
1073
|
-
error.actualIssuer =
|
|
1167
|
+
error.expectedIssuer = subject.attributes;
|
|
1168
|
+
error.actualIssuer = issuer.attributes;
|
|
1074
1169
|
throw error;
|
|
1075
1170
|
}
|
|
1076
1171
|
|
|
1077
1172
|
var md = child.md;
|
|
1078
1173
|
if(md === null) {
|
|
1079
|
-
//
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
md = forge.md.sha1.create();
|
|
1085
|
-
break;
|
|
1086
|
-
case 'md5WithRSAEncryption':
|
|
1087
|
-
md = forge.md.md5.create();
|
|
1088
|
-
break;
|
|
1089
|
-
case 'sha256WithRSAEncryption':
|
|
1090
|
-
md = forge.md.sha256.create();
|
|
1091
|
-
break;
|
|
1092
|
-
case 'sha384WithRSAEncryption':
|
|
1093
|
-
md = forge.md.sha384.create();
|
|
1094
|
-
break;
|
|
1095
|
-
case 'sha512WithRSAEncryption':
|
|
1096
|
-
md = forge.md.sha512.create();
|
|
1097
|
-
break;
|
|
1098
|
-
case 'RSASSA-PSS':
|
|
1099
|
-
md = forge.md.sha256.create();
|
|
1100
|
-
break;
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
if(md === null) {
|
|
1104
|
-
var error = new Error('Could not compute certificate digest. ' +
|
|
1105
|
-
'Unknown signature OID.');
|
|
1106
|
-
error.signatureOid = child.signatureOid;
|
|
1107
|
-
throw error;
|
|
1108
|
-
}
|
|
1174
|
+
// create digest for OID signature types
|
|
1175
|
+
md = _createSignatureDigest({
|
|
1176
|
+
signatureOid: child.signatureOid,
|
|
1177
|
+
type: 'certificate'
|
|
1178
|
+
});
|
|
1109
1179
|
|
|
1110
1180
|
// produce DER formatted TBSCertificate and digest it
|
|
1111
1181
|
var tbsCertificate = child.tbsCertificate || pki.getTBSCertificate(child);
|
|
@@ -1114,52 +1184,9 @@ pki.createCertificate = function() {
|
|
|
1114
1184
|
}
|
|
1115
1185
|
|
|
1116
1186
|
if(md !== null) {
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
case oids.sha1WithRSAEncryption:
|
|
1121
|
-
scheme = undefined; /* use PKCS#1 v1.5 padding scheme */
|
|
1122
|
-
break;
|
|
1123
|
-
case oids['RSASSA-PSS']:
|
|
1124
|
-
var hash, mgf;
|
|
1125
|
-
|
|
1126
|
-
/* initialize mgf */
|
|
1127
|
-
hash = oids[child.signatureParameters.mgf.hash.algorithmOid];
|
|
1128
|
-
if(hash === undefined || forge.md[hash] === undefined) {
|
|
1129
|
-
var error = new Error('Unsupported MGF hash function.');
|
|
1130
|
-
error.oid = child.signatureParameters.mgf.hash.algorithmOid;
|
|
1131
|
-
error.name = hash;
|
|
1132
|
-
throw error;
|
|
1133
|
-
}
|
|
1134
|
-
|
|
1135
|
-
mgf = oids[child.signatureParameters.mgf.algorithmOid];
|
|
1136
|
-
if(mgf === undefined || forge.mgf[mgf] === undefined) {
|
|
1137
|
-
var error = new Error('Unsupported MGF function.');
|
|
1138
|
-
error.oid = child.signatureParameters.mgf.algorithmOid;
|
|
1139
|
-
error.name = mgf;
|
|
1140
|
-
throw error;
|
|
1141
|
-
}
|
|
1142
|
-
|
|
1143
|
-
mgf = forge.mgf[mgf].create(forge.md[hash].create());
|
|
1144
|
-
|
|
1145
|
-
/* initialize hash function */
|
|
1146
|
-
hash = oids[child.signatureParameters.hash.algorithmOid];
|
|
1147
|
-
if(hash === undefined || forge.md[hash] === undefined) {
|
|
1148
|
-
throw {
|
|
1149
|
-
message: 'Unsupported RSASSA-PSS hash function.',
|
|
1150
|
-
oid: child.signatureParameters.hash.algorithmOid,
|
|
1151
|
-
name: hash
|
|
1152
|
-
};
|
|
1153
|
-
}
|
|
1154
|
-
|
|
1155
|
-
scheme = forge.pss.create(forge.md[hash].create(), mgf,
|
|
1156
|
-
child.signatureParameters.saltLength);
|
|
1157
|
-
break;
|
|
1158
|
-
}
|
|
1159
|
-
|
|
1160
|
-
// verify signature on cert using public key
|
|
1161
|
-
rval = cert.publicKey.verify(
|
|
1162
|
-
md.digest().getBytes(), child.signature, scheme);
|
|
1187
|
+
rval = _verifySignature({
|
|
1188
|
+
certificate: cert, md: md, signature: child.signature
|
|
1189
|
+
});
|
|
1163
1190
|
}
|
|
1164
1191
|
|
|
1165
1192
|
return rval;
|
|
@@ -1333,37 +1360,11 @@ pki.certificateFromAsn1 = function(obj, computeHash) {
|
|
|
1333
1360
|
cert.tbsCertificate = capture.tbsCertificate;
|
|
1334
1361
|
|
|
1335
1362
|
if(computeHash) {
|
|
1336
|
-
//
|
|
1337
|
-
cert.md =
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
case 'sha1WithRSAEncryption':
|
|
1342
|
-
cert.md = forge.md.sha1.create();
|
|
1343
|
-
break;
|
|
1344
|
-
case 'md5WithRSAEncryption':
|
|
1345
|
-
cert.md = forge.md.md5.create();
|
|
1346
|
-
break;
|
|
1347
|
-
case 'sha256WithRSAEncryption':
|
|
1348
|
-
cert.md = forge.md.sha256.create();
|
|
1349
|
-
break;
|
|
1350
|
-
case 'sha384WithRSAEncryption':
|
|
1351
|
-
cert.md = forge.md.sha384.create();
|
|
1352
|
-
break;
|
|
1353
|
-
case 'sha512WithRSAEncryption':
|
|
1354
|
-
cert.md = forge.md.sha512.create();
|
|
1355
|
-
break;
|
|
1356
|
-
case 'RSASSA-PSS':
|
|
1357
|
-
cert.md = forge.md.sha256.create();
|
|
1358
|
-
break;
|
|
1359
|
-
}
|
|
1360
|
-
}
|
|
1361
|
-
if(cert.md === null) {
|
|
1362
|
-
var error = new Error('Could not compute certificate digest. ' +
|
|
1363
|
-
'Unknown signature OID.');
|
|
1364
|
-
error.signatureOid = cert.signatureOid;
|
|
1365
|
-
throw error;
|
|
1366
|
-
}
|
|
1363
|
+
// create digest for OID signature type
|
|
1364
|
+
cert.md = _createSignatureDigest({
|
|
1365
|
+
signatureOid: cert.signatureOid,
|
|
1366
|
+
type: 'certificate'
|
|
1367
|
+
});
|
|
1367
1368
|
|
|
1368
1369
|
// produce DER formatted TBSCertificate and digest it
|
|
1369
1370
|
var bytes = asn1.toDer(cert.tbsCertificate);
|
|
@@ -1681,37 +1682,11 @@ pki.certificationRequestFromAsn1 = function(obj, computeHash) {
|
|
|
1681
1682
|
csr.certificationRequestInfo = capture.certificationRequestInfo;
|
|
1682
1683
|
|
|
1683
1684
|
if(computeHash) {
|
|
1684
|
-
//
|
|
1685
|
-
csr.md =
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
case 'sha1WithRSAEncryption':
|
|
1690
|
-
csr.md = forge.md.sha1.create();
|
|
1691
|
-
break;
|
|
1692
|
-
case 'md5WithRSAEncryption':
|
|
1693
|
-
csr.md = forge.md.md5.create();
|
|
1694
|
-
break;
|
|
1695
|
-
case 'sha256WithRSAEncryption':
|
|
1696
|
-
csr.md = forge.md.sha256.create();
|
|
1697
|
-
break;
|
|
1698
|
-
case 'sha384WithRSAEncryption':
|
|
1699
|
-
csr.md = forge.md.sha384.create();
|
|
1700
|
-
break;
|
|
1701
|
-
case 'sha512WithRSAEncryption':
|
|
1702
|
-
csr.md = forge.md.sha512.create();
|
|
1703
|
-
break;
|
|
1704
|
-
case 'RSASSA-PSS':
|
|
1705
|
-
csr.md = forge.md.sha256.create();
|
|
1706
|
-
break;
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
if(csr.md === null) {
|
|
1710
|
-
var error = new Error('Could not compute certification request digest. ' +
|
|
1711
|
-
'Unknown signature OID.');
|
|
1712
|
-
error.signatureOid = csr.signatureOid;
|
|
1713
|
-
throw error;
|
|
1714
|
-
}
|
|
1685
|
+
// create digest for OID signature type
|
|
1686
|
+
csr.md = _createSignatureDigest({
|
|
1687
|
+
signatureOid: csr.signatureOid,
|
|
1688
|
+
type: 'certification request'
|
|
1689
|
+
});
|
|
1715
1690
|
|
|
1716
1691
|
// produce DER formatted CertificationRequestInfo and digest it
|
|
1717
1692
|
var bytes = asn1.toDer(csr.certificationRequestInfo);
|
|
@@ -1851,38 +1826,10 @@ pki.createCertificationRequest = function() {
|
|
|
1851
1826
|
|
|
1852
1827
|
var md = csr.md;
|
|
1853
1828
|
if(md === null) {
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
switch(oid) {
|
|
1859
|
-
case 'sha1WithRSAEncryption':
|
|
1860
|
-
md = forge.md.sha1.create();
|
|
1861
|
-
break;
|
|
1862
|
-
case 'md5WithRSAEncryption':
|
|
1863
|
-
md = forge.md.md5.create();
|
|
1864
|
-
break;
|
|
1865
|
-
case 'sha256WithRSAEncryption':
|
|
1866
|
-
md = forge.md.sha256.create();
|
|
1867
|
-
break;
|
|
1868
|
-
case 'sha384WithRSAEncryption':
|
|
1869
|
-
md = forge.md.sha384.create();
|
|
1870
|
-
break;
|
|
1871
|
-
case 'sha512WithRSAEncryption':
|
|
1872
|
-
md = forge.md.sha512.create();
|
|
1873
|
-
break;
|
|
1874
|
-
case 'RSASSA-PSS':
|
|
1875
|
-
md = forge.md.sha256.create();
|
|
1876
|
-
break;
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
if(md === null) {
|
|
1880
|
-
var error = new Error(
|
|
1881
|
-
'Could not compute certification request digest. ' +
|
|
1882
|
-
'Unknown signature OID.');
|
|
1883
|
-
error.signatureOid = csr.signatureOid;
|
|
1884
|
-
throw error;
|
|
1885
|
-
}
|
|
1829
|
+
md = _createSignatureDigest({
|
|
1830
|
+
signatureOid: csr.signatureOid,
|
|
1831
|
+
type: 'certification request'
|
|
1832
|
+
});
|
|
1886
1833
|
|
|
1887
1834
|
// produce DER formatted CertificationRequestInfo and digest it
|
|
1888
1835
|
var cri = csr.certificationRequestInfo ||
|
|
@@ -1892,51 +1839,9 @@ pki.createCertificationRequest = function() {
|
|
|
1892
1839
|
}
|
|
1893
1840
|
|
|
1894
1841
|
if(md !== null) {
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
case oids.sha1WithRSAEncryption:
|
|
1899
|
-
/* use PKCS#1 v1.5 padding scheme */
|
|
1900
|
-
break;
|
|
1901
|
-
case oids['RSASSA-PSS']:
|
|
1902
|
-
var hash, mgf;
|
|
1903
|
-
|
|
1904
|
-
/* initialize mgf */
|
|
1905
|
-
hash = oids[csr.signatureParameters.mgf.hash.algorithmOid];
|
|
1906
|
-
if(hash === undefined || forge.md[hash] === undefined) {
|
|
1907
|
-
var error = new Error('Unsupported MGF hash function.');
|
|
1908
|
-
error.oid = csr.signatureParameters.mgf.hash.algorithmOid;
|
|
1909
|
-
error.name = hash;
|
|
1910
|
-
throw error;
|
|
1911
|
-
}
|
|
1912
|
-
|
|
1913
|
-
mgf = oids[csr.signatureParameters.mgf.algorithmOid];
|
|
1914
|
-
if(mgf === undefined || forge.mgf[mgf] === undefined) {
|
|
1915
|
-
var error = new Error('Unsupported MGF function.');
|
|
1916
|
-
error.oid = csr.signatureParameters.mgf.algorithmOid;
|
|
1917
|
-
error.name = mgf;
|
|
1918
|
-
throw error;
|
|
1919
|
-
}
|
|
1920
|
-
|
|
1921
|
-
mgf = forge.mgf[mgf].create(forge.md[hash].create());
|
|
1922
|
-
|
|
1923
|
-
/* initialize hash function */
|
|
1924
|
-
hash = oids[csr.signatureParameters.hash.algorithmOid];
|
|
1925
|
-
if(hash === undefined || forge.md[hash] === undefined) {
|
|
1926
|
-
var error = new Error('Unsupported RSASSA-PSS hash function.');
|
|
1927
|
-
error.oid = csr.signatureParameters.hash.algorithmOid;
|
|
1928
|
-
error.name = hash;
|
|
1929
|
-
throw error;
|
|
1930
|
-
}
|
|
1931
|
-
|
|
1932
|
-
scheme = forge.pss.create(forge.md[hash].create(), mgf,
|
|
1933
|
-
csr.signatureParameters.saltLength);
|
|
1934
|
-
break;
|
|
1935
|
-
}
|
|
1936
|
-
|
|
1937
|
-
// verify signature on csr using its public key
|
|
1938
|
-
rval = csr.publicKey.verify(
|
|
1939
|
-
md.digest().getBytes(), csr.signature, scheme);
|
|
1842
|
+
rval = _verifySignature({
|
|
1843
|
+
certificate: csr, md: md, signature: csr.signature
|
|
1844
|
+
});
|
|
1940
1845
|
}
|
|
1941
1846
|
|
|
1942
1847
|
return rval;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-forge",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "JavaScript implementations of network transports, cryptography, ciphers, PKI, message digests, and various utilities.",
|
|
5
5
|
"homepage": "https://github.com/digitalbazaar/forge",
|
|
6
6
|
"author": {
|