saml 2.0.1 → 3.0.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/.github/workflows/semgrep.yml +15 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/jsLibraryMappings.xml +6 -0
- package/.idea/node-saml.iml +1 -0
- package/.idea/prettier.xml +7 -0
- package/.idea/sonarlint/issuestore/1/5/152d3f39906314d7648bee688e6cf0e074eac700 +0 -0
- package/.idea/sonarlint/issuestore/1/6/16c55078736dc7b024c5f6aee3724b578a6f762e +0 -0
- package/.idea/sonarlint/issuestore/7/0/7030d0b2f71b999ff89a343de08c414af32fc93a +0 -0
- package/.idea/sonarlint/issuestore/9/7/97145ab6a3556e0c76c6cdf36c0a30bb088f382f +2 -0
- package/.idea/sonarlint/issuestore/9/8/988145bf095565ed2790e577ca6610aae3f148eb +0 -0
- package/.idea/sonarlint/issuestore/a/b/ab09011fa121d0a2bb9fa4ca76094f2482b902b7 +0 -0
- package/.idea/sonarlint/issuestore/b/f/bf580f9fe6b7aafd1864a1b474928848f50d9486 +0 -0
- package/.idea/sonarlint/issuestore/index.pb +15 -0
- package/CHANGELOG.md +11 -0
- package/lib/utils.js +34 -16
- package/lib/xml/encrypt.js +23 -5
- package/lib/xml/sign.js +54 -35
- package/package.json +1 -1
- package/test/saml11.tests.js +64 -0
- package/test/saml20.tests.js +132 -0
- package/test/test-auth0-chain.pem +160 -0
- package/test/test-auth0.der +0 -0
- package/test/utils.tests.js +62 -10
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
name: Semgrep
|
|
2
|
+
on:
|
|
3
|
+
pull_request: {}
|
|
4
|
+
push:
|
|
5
|
+
branches: ["master"]
|
|
6
|
+
jobs:
|
|
7
|
+
semgrep:
|
|
8
|
+
name: Scan
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
if: (github.actor != 'dependabot[bot]' && github.actor != 'snyk-bot')
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v2
|
|
13
|
+
- uses: returntocorp/semgrep-action@v1
|
|
14
|
+
with:
|
|
15
|
+
publishToken: ${{ secrets.SEMGREP_APP_TOKEN }}
|
package/.idea/node-saml.iml
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
<excludeFolder url="file://$MODULE_DIR$/temp" />
|
|
6
6
|
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
|
|
7
7
|
<excludeFolder url="file://$MODULE_DIR$/tmp" />
|
|
8
|
+
<excludeFolder url="file://$MODULE_DIR$/.idea" />
|
|
8
9
|
</content>
|
|
9
10
|
<orderEntry type="inheritedJdk" />
|
|
10
11
|
<orderEntry type="sourceFolder" forTests="false" />
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
<
|
|
3
|
+
CHANGELOG.md,a/b/ab09011fa121d0a2bb9fa4ca76094f2482b902b7
|
|
4
|
+
G
|
|
5
|
+
test/test-auth0_rsa.pub,1/6/16c55078736dc7b024c5f6aee3724b578a6f762e
|
|
6
|
+
<
|
|
7
|
+
package.json,7/0/7030d0b2f71b999ff89a343de08c414af32fc93a
|
|
8
|
+
C
|
|
9
|
+
test/test-auth0.pem,9/8/988145bf095565ed2790e577ca6610aae3f148eb
|
|
10
|
+
C
|
|
11
|
+
test/test-auth0.key,b/f/bf580f9fe6b7aafd1864a1b474928848f50d9486
|
|
12
|
+
=
|
|
13
|
+
|
|
14
|
+
I
|
|
15
|
+
test/test-auth0-chain.pem,1/5/152d3f39906314d7648bee688e6cf0e074eac700
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
## [3.0.0](https://github.com/auth0/node-saml/compare/v2.0.1...v3.0.0) (2022-05-12)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
* handle poorly formatted PEM files (#85)
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* handle poorly formatted PEM files ([#85](https://github.com/auth0/node-saml/issues/85)) ([8830a23](https://github.com/auth0/node-saml/commit/8830a238d33e2e198acd81fb6d972583848bfe26))
|
|
15
|
+
|
|
5
16
|
### [2.0.1](https://github.com/auth0/node-saml/compare/v2.0.0...v2.0.1) (2022-02-09)
|
|
6
17
|
|
|
7
18
|
|
package/lib/utils.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const Parser = require('@xmldom/xmldom').DOMParser;
|
|
3
3
|
|
|
4
4
|
exports.pemToCert = function(pem) {
|
|
5
|
-
|
|
5
|
+
const cert = /-----BEGIN CERTIFICATE-----([^-]*)-----END CERTIFICATE-----/g.exec(pem.toString());
|
|
6
6
|
if (cert && cert.length > 0) {
|
|
7
7
|
return cert[1].replace(/[\n|\r\n]/g, '');
|
|
8
8
|
}
|
|
@@ -29,11 +29,11 @@ exports.reportError = function(err, callback){
|
|
|
29
29
|
* @api private
|
|
30
30
|
*/
|
|
31
31
|
exports.uid = function(len) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
const buf = []
|
|
33
|
+
, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
|
34
|
+
, charlen = chars.length;
|
|
35
35
|
|
|
36
|
-
for (
|
|
36
|
+
for (let i = 0; i < len; ++i) {
|
|
37
37
|
buf.push(chars[getRandomInt(0, charlen - 1)]);
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -41,16 +41,15 @@ exports.uid = function(len) {
|
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
exports.removeWhitespace = function(xml) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return trimmed;
|
|
44
|
+
return xml
|
|
45
|
+
.replace(/\r\n/g, '')
|
|
46
|
+
.replace(/\n/g, '')
|
|
47
|
+
.replace(/>(\s*)</g, '><') //unindent
|
|
48
|
+
.trim();
|
|
50
49
|
};
|
|
51
50
|
|
|
52
51
|
/**
|
|
53
|
-
*
|
|
52
|
+
* Return a random int, used by `utils.uid()`
|
|
54
53
|
*
|
|
55
54
|
* @param {Number} min
|
|
56
55
|
* @param {Number} max
|
|
@@ -69,10 +68,29 @@ function getRandomInt(min, max) {
|
|
|
69
68
|
* @return {function(): Node}
|
|
70
69
|
*/
|
|
71
70
|
exports.factoryForNode = function factoryForNode(pathToTemplate) {
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
const template = fs.readFileSync(pathToTemplate);
|
|
72
|
+
const prototypeDoc = new Parser().parseFromString(template.toString());
|
|
74
73
|
|
|
75
74
|
return function () {
|
|
76
75
|
return prototypeDoc.cloneNode(true);
|
|
77
76
|
};
|
|
78
77
|
};
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Standardizes PEM content to match the spec (best effort)
|
|
81
|
+
*
|
|
82
|
+
* @param pem {Buffer} The PEM content to standardize
|
|
83
|
+
* @returns {Buffer} The standardized PEM. Original will be returned unmodified if the content is not PEM.
|
|
84
|
+
*/
|
|
85
|
+
exports.fixPemFormatting = function (pem) {
|
|
86
|
+
let pemEntries = pem.toString().matchAll(/([-]{5}[^-\r\n]+[-]{5})([^-]*)([-]{5}[^-\r\n]+[-]{5})/g);
|
|
87
|
+
let fixedPem = ''
|
|
88
|
+
for (const pemParts of pemEntries) {
|
|
89
|
+
fixedPem = fixedPem.concat(`${pemParts[1]}\n${pemParts[2].replaceAll(/[\r\n]/g, '')}\n${pemParts[3]}\n`)
|
|
90
|
+
}
|
|
91
|
+
if (fixedPem.length === 0) {
|
|
92
|
+
return pem;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return Buffer.from(fixedPem)
|
|
96
|
+
}
|
package/lib/xml/encrypt.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
const xmlenc = require('xml-encryption');
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const utils = require('../utils');
|
|
4
4
|
|
|
5
5
|
exports.fromEncryptXmlOptions = function (options) {
|
|
6
6
|
if (!options.encryptionCert) {
|
|
7
7
|
return this.unencrypted;
|
|
8
8
|
} else {
|
|
9
|
-
|
|
9
|
+
const encryptOptions = {
|
|
10
10
|
rsa_pub: options.encryptionPublicKey,
|
|
11
11
|
pem: options.encryptionCert,
|
|
12
12
|
encryptionAlgorithm: options.encryptionAlgorithm || 'http://www.w3.org/2001/04/xmlenc#aes256-cbc',
|
|
@@ -29,8 +29,26 @@ exports.unencrypted = function (xml, callback) {
|
|
|
29
29
|
exports.encrypted = function (encryptOptions) {
|
|
30
30
|
return function encrypt(xml, callback) {
|
|
31
31
|
xmlenc.encrypt(xml, encryptOptions, function (err, encrypted) {
|
|
32
|
-
if (err)
|
|
33
|
-
|
|
32
|
+
if (err) {
|
|
33
|
+
// Attempt to fix errors and retry
|
|
34
|
+
xmlenc.encrypt(
|
|
35
|
+
xml,
|
|
36
|
+
{
|
|
37
|
+
...encryptOptions,
|
|
38
|
+
rsa_pub: utils.fixPemFormatting(encryptOptions.rsa_pub),
|
|
39
|
+
pem: utils.fixPemFormatting(encryptOptions.pem),
|
|
40
|
+
},
|
|
41
|
+
function (retryErr, retryEncrypted) {
|
|
42
|
+
if (retryErr) {
|
|
43
|
+
return callback(retryErr);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
callback(null, utils.removeWhitespace(retryEncrypted));
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
} else {
|
|
50
|
+
callback(null, utils.removeWhitespace(encrypted));
|
|
51
|
+
}
|
|
34
52
|
});
|
|
35
53
|
};
|
|
36
54
|
};
|
package/lib/xml/sign.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
const utils = require('../utils');
|
|
2
|
+
const SignedXml = require('xml-crypto').SignedXml;
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const algorithms = {
|
|
5
5
|
signature: {
|
|
6
6
|
'rsa-sha256': 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
|
|
7
|
-
'rsa-sha1':
|
|
7
|
+
'rsa-sha1': 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'
|
|
8
8
|
},
|
|
9
9
|
digest: {
|
|
10
10
|
'sha256': 'http://www.w3.org/2001/04/xmlenc#sha256',
|
|
@@ -22,16 +22,16 @@ exports.fromSignXmlOptions = function (options) {
|
|
|
22
22
|
if (!options.xpathToNodeBeforeSignature)
|
|
23
23
|
throw new Error('xpathToNodeBeforeSignature is required')
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
const key = options.key;
|
|
26
|
+
const pem = options.cert;
|
|
27
|
+
const signatureAlgorithm = options.signatureAlgorithm || 'rsa-sha256';
|
|
28
|
+
const digestAlgorithm = options.digestAlgorithm || 'sha256';
|
|
29
|
+
const signatureNamespacePrefix = (function (prefix) {
|
|
30
30
|
// 0.10.1 added prefix, but we want to name it signatureNamespacePrefix - This is just to keep supporting prefix
|
|
31
31
|
return typeof prefix === 'string' ? prefix : '';
|
|
32
32
|
})(options.signatureNamespacePrefix || options.prefix);
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
const xpathToNodeBeforeSignature = options.xpathToNodeBeforeSignature;
|
|
34
|
+
const idAttribute = options.signatureIdAttribute;
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* @param {Document} doc
|
|
@@ -39,44 +39,63 @@ exports.fromSignXmlOptions = function (options) {
|
|
|
39
39
|
* @return {string}
|
|
40
40
|
*/
|
|
41
41
|
return function signXmlDocument(doc, callback) {
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
function sign(key) {
|
|
43
|
+
const unsigned = exports.unsigned(doc);
|
|
44
|
+
const cert = utils.pemToCert(pem);
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
const sig = new SignedXml(null, {
|
|
47
|
+
signatureAlgorithm: algorithms.signature[signatureAlgorithm],
|
|
48
|
+
idAttribute: idAttribute
|
|
49
|
+
});
|
|
50
|
+
sig.addReference("//*[local-name(.)='Assertion']",
|
|
51
|
+
["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/2001/10/xml-exc-c14n#"],
|
|
52
|
+
algorithms.digest[digestAlgorithm]);
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
sig.signingKey = key;
|
|
51
55
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
sig.keyInfoProvider = {
|
|
57
|
+
getKeyInfo: function (key, prefix) {
|
|
58
|
+
prefix = prefix ? prefix + ':' : prefix;
|
|
59
|
+
return "<" + prefix + "X509Data><" + prefix + "X509Certificate>" + cert + "</" + prefix + "X509Certificate></" + prefix + "X509Data>";
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
sig.computeSignature(unsigned, {
|
|
64
|
+
location: {reference: xpathToNodeBeforeSignature, action: 'after'},
|
|
65
|
+
prefix: signatureNamespacePrefix
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return sig.getSignedXml();
|
|
69
|
+
}
|
|
58
70
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
71
|
+
let signed
|
|
72
|
+
try {
|
|
73
|
+
try {
|
|
74
|
+
signed = sign(key)
|
|
75
|
+
} catch (err) {
|
|
76
|
+
signed = sign(utils.fixPemFormatting(key))
|
|
77
|
+
}
|
|
63
78
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
79
|
+
if (callback) {
|
|
80
|
+
setImmediate(callback, null, signed);
|
|
81
|
+
} else {
|
|
82
|
+
return signed;
|
|
83
|
+
}
|
|
84
|
+
} catch (e) {
|
|
85
|
+
if (callback) {
|
|
86
|
+
setImmediate(callback, e)
|
|
87
|
+
}
|
|
88
|
+
throw e
|
|
69
89
|
}
|
|
70
90
|
};
|
|
71
91
|
};
|
|
72
|
-
|
|
73
92
|
/**
|
|
74
93
|
* @param {Document} doc
|
|
75
94
|
* @param {Function} [callback]
|
|
76
95
|
* @return {string}
|
|
77
96
|
*/
|
|
78
97
|
exports.unsigned = function (doc, callback) {
|
|
79
|
-
|
|
98
|
+
const xml = utils.removeWhitespace(doc.toString());
|
|
80
99
|
if (callback) {
|
|
81
100
|
setImmediate(callback, null, xml)
|
|
82
101
|
} else {
|
package/package.json
CHANGED
package/test/saml11.tests.js
CHANGED
|
@@ -46,6 +46,32 @@ describe('saml 1.1', function () {
|
|
|
46
46
|
assertSignature(signedAssertion, options);
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
+
it('should not error when cert is missing newlines', function () {
|
|
50
|
+
// cert created with:
|
|
51
|
+
// openssl req -x509 -new -newkey rsa:2048 -nodes -subj '/CN=auth0.auth0.com/O=Auth0 LLC/C=US/ST=Washington/L=Redmond' -keyout auth0.key -out auth0.pem
|
|
52
|
+
|
|
53
|
+
var options = {
|
|
54
|
+
cert: fs.readFileSync(__dirname + '/test-auth0.pem'),
|
|
55
|
+
key: fs.readFileSync(__dirname + '/test-auth0.key')
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
var signedAssertion = saml11[createAssertion]({...options, cert: Buffer.from(options.cert.toString().replaceAll(/[\r\n]/g, ''))});
|
|
59
|
+
assertSignature(signedAssertion, options);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should not error when key is missing newlines', function () {
|
|
63
|
+
// cert created with:
|
|
64
|
+
// openssl req -x509 -new -newkey rsa:2048 -nodes -subj '/CN=auth0.auth0.com/O=Auth0 LLC/C=US/ST=Washington/L=Redmond' -keyout auth0.key -out auth0.pem
|
|
65
|
+
|
|
66
|
+
var options = {
|
|
67
|
+
cert: fs.readFileSync(__dirname + '/test-auth0.pem'),
|
|
68
|
+
key: fs.readFileSync(__dirname + '/test-auth0.key')
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
var signedAssertion = saml11[createAssertion]({...options, key: Buffer.from(options.key.toString().replaceAll(/[\r\n]/g, ''))});
|
|
72
|
+
assertSignature(signedAssertion, options);
|
|
73
|
+
});
|
|
74
|
+
|
|
49
75
|
it('should support specifying Issuer property', function () {
|
|
50
76
|
var options = {
|
|
51
77
|
cert: fs.readFileSync(__dirname + '/test-auth0.pem'),
|
|
@@ -350,6 +376,44 @@ describe('saml 1.1', function () {
|
|
|
350
376
|
});
|
|
351
377
|
});
|
|
352
378
|
|
|
379
|
+
it('should not error when encryptionPublicKey is missing newlines', function (done) {
|
|
380
|
+
var options = {
|
|
381
|
+
cert: fs.readFileSync(__dirname + '/test-auth0.pem'),
|
|
382
|
+
key: fs.readFileSync(__dirname + '/test-auth0.key'),
|
|
383
|
+
encryptionPublicKey: Buffer.from(fs.readFileSync(__dirname + '/test-auth0_rsa.pub').toString().replaceAll(/[\r\n]/g, '')),
|
|
384
|
+
encryptionCert: fs.readFileSync(__dirname + '/test-auth0.pem')
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
saml11[createAssertion](options, function(err, encrypted) {
|
|
388
|
+
if (err) return done(err);
|
|
389
|
+
|
|
390
|
+
xmlenc.decrypt(encrypted, { key: fs.readFileSync(__dirname + '/test-auth0.key')}, function(err, decrypted) {
|
|
391
|
+
if (err) return done(err);
|
|
392
|
+
assertSignature(decrypted, options);
|
|
393
|
+
done();
|
|
394
|
+
});
|
|
395
|
+
});
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
it('should not error when encryptionCert is missing newlines', function (done) {
|
|
399
|
+
var options = {
|
|
400
|
+
cert: fs.readFileSync(__dirname + '/test-auth0.pem'),
|
|
401
|
+
key: fs.readFileSync(__dirname + '/test-auth0.key'),
|
|
402
|
+
encryptionPublicKey: fs.readFileSync(__dirname + '/test-auth0_rsa.pub'),
|
|
403
|
+
encryptionCert: Buffer.from(fs.readFileSync(__dirname + '/test-auth0.pem').toString().replaceAll(/[\r\n]/g, ''))
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
saml11[createAssertion](options, function(err, encrypted) {
|
|
407
|
+
if (err) return done(err);
|
|
408
|
+
|
|
409
|
+
xmlenc.decrypt(encrypted, { key: fs.readFileSync(__dirname + '/test-auth0.key')}, function(err, decrypted) {
|
|
410
|
+
if (err) return done(err);
|
|
411
|
+
assertSignature(decrypted, options);
|
|
412
|
+
done();
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
|
|
353
417
|
it('should support holder-of-key suject confirmationmethod', function (done) {
|
|
354
418
|
var options = {
|
|
355
419
|
cert: fs.readFileSync(__dirname + '/test-auth0.pem'),
|
package/test/saml20.tests.js
CHANGED
|
@@ -77,6 +77,96 @@ describe('saml 2.0', function () {
|
|
|
77
77
|
assert.equal('urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified', authnContextClassRef.textContent);
|
|
78
78
|
});
|
|
79
79
|
|
|
80
|
+
it('should not error when cert is missing newlines', function () {
|
|
81
|
+
var options = {
|
|
82
|
+
cert: fs.readFileSync(__dirname + '/test-auth0.pem'),
|
|
83
|
+
key: fs.readFileSync(__dirname + '/test-auth0.key'),
|
|
84
|
+
issuer: 'urn:issuer',
|
|
85
|
+
lifetimeInSeconds: 600,
|
|
86
|
+
audiences: 'urn:myapp',
|
|
87
|
+
attributes: {
|
|
88
|
+
'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress': 'foo@bar.com',
|
|
89
|
+
'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name': 'Foo Bar'
|
|
90
|
+
},
|
|
91
|
+
nameIdentifier: 'foo',
|
|
92
|
+
nameIdentifierFormat: 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
var signedAssertion = saml[createAssertion]({...options, cert: Buffer.from(options.cert.toString().replaceAll(/[\r\n]/g, ''))});
|
|
96
|
+
assertSignature(signedAssertion, options);
|
|
97
|
+
|
|
98
|
+
var nameIdentifier = utils.getNameID(signedAssertion);
|
|
99
|
+
assert.equal('foo', nameIdentifier.textContent);
|
|
100
|
+
assert.equal('urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified', nameIdentifier.getAttribute('Format'));
|
|
101
|
+
|
|
102
|
+
var attributes = utils.getAttributes(signedAssertion);
|
|
103
|
+
assert.equal(2, attributes.length);
|
|
104
|
+
assert.equal('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress', attributes[0].getAttribute('Name'));
|
|
105
|
+
assert.equal('foo@bar.com', attributes[0].textContent);
|
|
106
|
+
assert.equal('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name', attributes[1].getAttribute('Name'));
|
|
107
|
+
assert.equal('Foo Bar', attributes[1].textContent);
|
|
108
|
+
|
|
109
|
+
assert.equal('urn:issuer', utils.getSaml2Issuer(signedAssertion).textContent);
|
|
110
|
+
|
|
111
|
+
var conditions = utils.getConditions(signedAssertion);
|
|
112
|
+
assert.equal(1, conditions.length);
|
|
113
|
+
var notBefore = conditions[0].getAttribute('NotBefore');
|
|
114
|
+
var notOnOrAfter = conditions[0].getAttribute('NotOnOrAfter');
|
|
115
|
+
should.ok(notBefore);
|
|
116
|
+
should.ok(notOnOrAfter);
|
|
117
|
+
|
|
118
|
+
var lifetime = Math.round((moment(notOnOrAfter).utc() - moment(notBefore).utc()) / 1000);
|
|
119
|
+
assert.equal(600, lifetime);
|
|
120
|
+
|
|
121
|
+
var authnContextClassRef = utils.getAuthnContextClassRef(signedAssertion);
|
|
122
|
+
assert.equal('urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified', authnContextClassRef.textContent);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('should not error when key is missing newlines', function () {
|
|
126
|
+
var options = {
|
|
127
|
+
cert: fs.readFileSync(__dirname + '/test-auth0.pem'),
|
|
128
|
+
key: fs.readFileSync(__dirname + '/test-auth0.key'),
|
|
129
|
+
issuer: 'urn:issuer',
|
|
130
|
+
lifetimeInSeconds: 600,
|
|
131
|
+
audiences: 'urn:myapp',
|
|
132
|
+
attributes: {
|
|
133
|
+
'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress': 'foo@bar.com',
|
|
134
|
+
'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name': 'Foo Bar'
|
|
135
|
+
},
|
|
136
|
+
nameIdentifier: 'foo',
|
|
137
|
+
nameIdentifierFormat: 'urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified'
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
var signedAssertion = saml[createAssertion]({...options, key: Buffer.from(options.key.toString().replaceAll(/[\r\n]/g, ''))});
|
|
141
|
+
assertSignature(signedAssertion, options);
|
|
142
|
+
|
|
143
|
+
var nameIdentifier = utils.getNameID(signedAssertion);
|
|
144
|
+
assert.equal('foo', nameIdentifier.textContent);
|
|
145
|
+
assert.equal('urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified', nameIdentifier.getAttribute('Format'));
|
|
146
|
+
|
|
147
|
+
var attributes = utils.getAttributes(signedAssertion);
|
|
148
|
+
assert.equal(2, attributes.length);
|
|
149
|
+
assert.equal('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress', attributes[0].getAttribute('Name'));
|
|
150
|
+
assert.equal('foo@bar.com', attributes[0].textContent);
|
|
151
|
+
assert.equal('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name', attributes[1].getAttribute('Name'));
|
|
152
|
+
assert.equal('Foo Bar', attributes[1].textContent);
|
|
153
|
+
|
|
154
|
+
assert.equal('urn:issuer', utils.getSaml2Issuer(signedAssertion).textContent);
|
|
155
|
+
|
|
156
|
+
var conditions = utils.getConditions(signedAssertion);
|
|
157
|
+
assert.equal(1, conditions.length);
|
|
158
|
+
var notBefore = conditions[0].getAttribute('NotBefore');
|
|
159
|
+
var notOnOrAfter = conditions[0].getAttribute('NotOnOrAfter');
|
|
160
|
+
should.ok(notBefore);
|
|
161
|
+
should.ok(notOnOrAfter);
|
|
162
|
+
|
|
163
|
+
var lifetime = Math.round((moment(notOnOrAfter).utc() - moment(notBefore).utc()) / 1000);
|
|
164
|
+
assert.equal(600, lifetime);
|
|
165
|
+
|
|
166
|
+
var authnContextClassRef = utils.getAuthnContextClassRef(signedAssertion);
|
|
167
|
+
assert.equal('urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified', authnContextClassRef.textContent);
|
|
168
|
+
});
|
|
169
|
+
|
|
80
170
|
it('should set attributes', function () {
|
|
81
171
|
var options = {
|
|
82
172
|
cert: fs.readFileSync(__dirname + '/test-auth0.pem'),
|
|
@@ -513,6 +603,48 @@ describe('saml 2.0', function () {
|
|
|
513
603
|
});
|
|
514
604
|
});
|
|
515
605
|
|
|
606
|
+
it('should not error when encryptionPublicKey is missing newline', function (done) {
|
|
607
|
+
var options = {
|
|
608
|
+
cert: fs.readFileSync(__dirname + '/test-auth0.pem'),
|
|
609
|
+
key: fs.readFileSync(__dirname + '/test-auth0.key'),
|
|
610
|
+
encryptionPublicKey: Buffer.from(fs.readFileSync(__dirname + '/test-auth0_rsa.pub').toString().replaceAll(/[\r\n]/g, '')),
|
|
611
|
+
encryptionCert: fs.readFileSync(__dirname + '/test-auth0.pem')
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
saml[createAssertion](options, function (err, encrypted) {
|
|
615
|
+
if (err) return done(err);
|
|
616
|
+
|
|
617
|
+
var encryptedData = utils.getEncryptedData(encrypted);
|
|
618
|
+
|
|
619
|
+
xmlenc.decrypt(encryptedData.toString(), { key: fs.readFileSync(__dirname + '/test-auth0.key') }, function (err, decrypted) {
|
|
620
|
+
if (err) return done(err);
|
|
621
|
+
assertSignature(decrypted, options);
|
|
622
|
+
done();
|
|
623
|
+
});
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
it('should not error when encryptionCert is missing newline', function (done) {
|
|
628
|
+
var options = {
|
|
629
|
+
cert: fs.readFileSync(__dirname + '/test-auth0.pem'),
|
|
630
|
+
key: fs.readFileSync(__dirname + '/test-auth0.key'),
|
|
631
|
+
encryptionPublicKey: fs.readFileSync(__dirname + '/test-auth0_rsa.pub'),
|
|
632
|
+
encryptionCert: Buffer.from(fs.readFileSync(__dirname + '/test-auth0.pem').toString().replaceAll(/[\r\n]/g, ''))
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
saml[createAssertion](options, function (err, encrypted) {
|
|
636
|
+
if (err) return done(err);
|
|
637
|
+
|
|
638
|
+
var encryptedData = utils.getEncryptedData(encrypted);
|
|
639
|
+
|
|
640
|
+
xmlenc.decrypt(encryptedData.toString(), { key: fs.readFileSync(__dirname + '/test-auth0.key') }, function (err, decrypted) {
|
|
641
|
+
if (err) return done(err);
|
|
642
|
+
assertSignature(decrypted, options);
|
|
643
|
+
done();
|
|
644
|
+
});
|
|
645
|
+
});
|
|
646
|
+
});
|
|
647
|
+
|
|
516
648
|
it('should set attributes', function (done) {
|
|
517
649
|
var options = {
|
|
518
650
|
cert: fs.readFileSync(__dirname + '/test-auth0.pem'),
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
|
2
|
+
MIIN1jCCDL6gAwIBAgIRANpcJKruPRmYEgAAAAAFph0wDQYJKoZIhvcNAQELBQAw
|
|
3
|
+
RjELMAkGA1UEBhMCVVMxIjAgBgNVBAoTGUdvb2dsZSBUcnVzdCBTZXJ2aWNlcyBM
|
|
4
|
+
TEMxEzARBgNVBAMTCkdUUyBDQSAxQzMwHhcNMjIwMzE3MTAyNjA4WhcNMjIwNjA5
|
|
5
|
+
MTAyNjA3WjAXMRUwEwYDVQQDDAwqLmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggq
|
|
6
|
+
hkjOPQMBBwNCAATtYBIFrigABQ4fmk2FmwNZhOsA5o5Z+V6m1npj4TjYTAxTLHoO
|
|
7
|
+
Qv2wKY7YfnQD6Jb7yQhc7Jma4UdPV/jplArko4ILtzCCC7MwDgYDVR0PAQH/BAQD
|
|
8
|
+
AgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYE
|
|
9
|
+
FI0OoPWBuG+vJ2nvFqPxQqYA+RyiMB8GA1UdIwQYMBaAFIp0f6+Fze6VzT2c0OJG
|
|
10
|
+
FPNxNR0nMGoGCCsGAQUFBwEBBF4wXDAnBggrBgEFBQcwAYYbaHR0cDovL29jc3Au
|
|
11
|
+
cGtpLmdvb2cvZ3RzMWMzMDEGCCsGAQUFBzAChiVodHRwOi8vcGtpLmdvb2cvcmVw
|
|
12
|
+
by9jZXJ0cy9ndHMxYzMuZGVyMIIJaAYDVR0RBIIJXzCCCVuCDCouZ29vZ2xlLmNv
|
|
13
|
+
bYIWKi5hcHBlbmdpbmUuZ29vZ2xlLmNvbYIJKi5iZG4uZGV2ghIqLmNsb3VkLmdv
|
|
14
|
+
b2dsZS5jb22CGCouY3Jvd2Rzb3VyY2UuZ29vZ2xlLmNvbYIYKi5kYXRhY29tcHV0
|
|
15
|
+
ZS5nb29nbGUuY29tggsqLmdvb2dsZS5jYYILKi5nb29nbGUuY2yCDiouZ29vZ2xl
|
|
16
|
+
LmNvLmlugg4qLmdvb2dsZS5jby5qcIIOKi5nb29nbGUuY28udWuCDyouZ29vZ2xl
|
|
17
|
+
LmNvbS5hcoIPKi5nb29nbGUuY29tLmF1gg8qLmdvb2dsZS5jb20uYnKCDyouZ29v
|
|
18
|
+
Z2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20udHKCDyou
|
|
19
|
+
Z29vZ2xlLmNvbS52boILKi5nb29nbGUuZGWCCyouZ29vZ2xlLmVzggsqLmdvb2ds
|
|
20
|
+
ZS5mcoILKi5nb29nbGUuaHWCCyouZ29vZ2xlLml0ggsqLmdvb2dsZS5ubIILKi5n
|
|
21
|
+
b29nbGUucGyCCyouZ29vZ2xlLnB0ghIqLmdvb2dsZWFkYXBpcy5jb22CDyouZ29v
|
|
22
|
+
Z2xlYXBpcy5jboIRKi5nb29nbGV2aWRlby5jb22CDCouZ3N0YXRpYy5jboIQKi5n
|
|
23
|
+
c3RhdGljLWNuLmNvbYIPZ29vZ2xlY25hcHBzLmNughEqLmdvb2dsZWNuYXBwcy5j
|
|
24
|
+
boIRZ29vZ2xlYXBwcy1jbi5jb22CEyouZ29vZ2xlYXBwcy1jbi5jb22CDGdrZWNu
|
|
25
|
+
YXBwcy5jboIOKi5na2VjbmFwcHMuY26CEmdvb2dsZWRvd25sb2Fkcy5jboIUKi5n
|
|
26
|
+
b29nbGVkb3dubG9hZHMuY26CEHJlY2FwdGNoYS5uZXQuY26CEioucmVjYXB0Y2hh
|
|
27
|
+
Lm5ldC5jboIQcmVjYXB0Y2hhLWNuLm5ldIISKi5yZWNhcHRjaGEtY24ubmV0ggt3
|
|
28
|
+
aWRldmluZS5jboINKi53aWRldmluZS5jboIRYW1wcHJvamVjdC5vcmcuY26CEyou
|
|
29
|
+
YW1wcHJvamVjdC5vcmcuY26CEWFtcHByb2plY3QubmV0LmNughMqLmFtcHByb2pl
|
|
30
|
+
Y3QubmV0LmNughdnb29nbGUtYW5hbHl0aWNzLWNuLmNvbYIZKi5nb29nbGUtYW5h
|
|
31
|
+
bHl0aWNzLWNuLmNvbYIXZ29vZ2xlYWRzZXJ2aWNlcy1jbi5jb22CGSouZ29vZ2xl
|
|
32
|
+
YWRzZXJ2aWNlcy1jbi5jb22CEWdvb2dsZXZhZHMtY24uY29tghMqLmdvb2dsZXZh
|
|
33
|
+
ZHMtY24uY29tghFnb29nbGVhcGlzLWNuLmNvbYITKi5nb29nbGVhcGlzLWNuLmNv
|
|
34
|
+
bYIVZ29vZ2xlb3B0aW1pemUtY24uY29tghcqLmdvb2dsZW9wdGltaXplLWNuLmNv
|
|
35
|
+
bYISZG91YmxlY2xpY2stY24ubmV0ghQqLmRvdWJsZWNsaWNrLWNuLm5ldIIYKi5m
|
|
36
|
+
bHMuZG91YmxlY2xpY2stY24ubmV0ghYqLmcuZG91YmxlY2xpY2stY24ubmV0gg5k
|
|
37
|
+
b3VibGVjbGljay5jboIQKi5kb3VibGVjbGljay5jboIUKi5mbHMuZG91YmxlY2xp
|
|
38
|
+
Y2suY26CEiouZy5kb3VibGVjbGljay5jboIRZGFydHNlYXJjaC1jbi5uZXSCEyou
|
|
39
|
+
ZGFydHNlYXJjaC1jbi5uZXSCHWdvb2dsZXRyYXZlbGFkc2VydmljZXMtY24uY29t
|
|
40
|
+
gh8qLmdvb2dsZXRyYXZlbGFkc2VydmljZXMtY24uY29tghhnb29nbGV0YWdzZXJ2
|
|
41
|
+
aWNlcy1jbi5jb22CGiouZ29vZ2xldGFnc2VydmljZXMtY24uY29tghdnb29nbGV0
|
|
42
|
+
YWdtYW5hZ2VyLWNuLmNvbYIZKi5nb29nbGV0YWdtYW5hZ2VyLWNuLmNvbYIYZ29v
|
|
43
|
+
Z2xlc3luZGljYXRpb24tY24uY29tghoqLmdvb2dsZXN5bmRpY2F0aW9uLWNuLmNv
|
|
44
|
+
bYIkKi5zYWZlZnJhbWUuZ29vZ2xlc3luZGljYXRpb24tY24uY29tghZhcHAtbWVh
|
|
45
|
+
c3VyZW1lbnQtY24uY29tghgqLmFwcC1tZWFzdXJlbWVudC1jbi5jb22CC2d2dDEt
|
|
46
|
+
Y24uY29tgg0qLmd2dDEtY24uY29tggtndnQyLWNuLmNvbYINKi5ndnQyLWNuLmNv
|
|
47
|
+
bYILMm1kbi1jbi5uZXSCDSouMm1kbi1jbi5uZXSCFGdvb2dsZWZsaWdodHMtY24u
|
|
48
|
+
bmV0ghYqLmdvb2dsZWZsaWdodHMtY24ubmV0ggxhZG1vYi1jbi5jb22CDiouYWRt
|
|
49
|
+
b2ItY24uY29tgg0qLmdzdGF0aWMuY29tghQqLm1ldHJpYy5nc3RhdGljLmNvbYIK
|
|
50
|
+
Ki5ndnQxLmNvbYIRKi5nY3BjZG4uZ3Z0MS5jb22CCiouZ3Z0Mi5jb22CDiouZ2Nw
|
|
51
|
+
Lmd2dDIuY29tghAqLnVybC5nb29nbGUuY29tghYqLnlvdXR1YmUtbm9jb29raWUu
|
|
52
|
+
Y29tggsqLnl0aW1nLmNvbYILYW5kcm9pZC5jb22CDSouYW5kcm9pZC5jb22CEyou
|
|
53
|
+
Zmxhc2guYW5kcm9pZC5jb22CBGcuY26CBiouZy5jboIEZy5jb4IGKi5nLmNvggZn
|
|
54
|
+
b28uZ2yCCnd3dy5nb28uZ2yCFGdvb2dsZS1hbmFseXRpY3MuY29tghYqLmdvb2ds
|
|
55
|
+
ZS1hbmFseXRpY3MuY29tggpnb29nbGUuY29tghJnb29nbGVjb21tZXJjZS5jb22C
|
|
56
|
+
FCouZ29vZ2xlY29tbWVyY2UuY29tgghnZ3BodC5jboIKKi5nZ3BodC5jboIKdXJj
|
|
57
|
+
aGluLmNvbYIMKi51cmNoaW4uY29tggh5b3V0dS5iZYILeW91dHViZS5jb22CDSou
|
|
58
|
+
eW91dHViZS5jb22CFHlvdXR1YmVlZHVjYXRpb24uY29tghYqLnlvdXR1YmVlZHVj
|
|
59
|
+
YXRpb24uY29tgg95b3V0dWJla2lkcy5jb22CESoueW91dHViZWtpZHMuY29tggV5
|
|
60
|
+
dC5iZYIHKi55dC5iZYIaYW5kcm9pZC5jbGllbnRzLmdvb2dsZS5jb22CG2RldmVs
|
|
61
|
+
b3Blci5hbmRyb2lkLmdvb2dsZS5jboIcZGV2ZWxvcGVycy5hbmRyb2lkLmdvb2ds
|
|
62
|
+
ZS5jboIYc291cmNlLmFuZHJvaWQuZ29vZ2xlLmNuMCEGA1UdIAQaMBgwCAYGZ4EM
|
|
63
|
+
AQIBMAwGCisGAQQB1nkCBQMwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybHMu
|
|
64
|
+
cGtpLmdvb2cvZ3RzMWMzL2ZWSnhiVi1LdG1rLmNybDCCAQMGCisGAQQB1nkCBAIE
|
|
65
|
+
gfQEgfEA7wB2ACl5vvCeOTkh8FZzn2Old+W+V32cYAr4+U1dJlwlXceEAAABf5eg
|
|
66
|
+
31sAAAQDAEcwRQIgKO/qyXDbVstUmyGkus1+NtSfQeBVeaah4uvJ4h5zODUCIQCr
|
|
67
|
+
IAXRbx0K9/GQGOK/OCcdH04AszWgCoHyR2AZjTaTfQB1AN+lXqtogk8fbK3uuF9O
|
|
68
|
+
PlrqzaISpGpejjsSwCBEXCpzAAABf5eg364AAAQDAEYwRAIgAr7Yby6/4yctoeiV
|
|
69
|
+
N84JsUBOFT8H5Wm9/JxeRhLzOOcCIAXVbvK2b8fGEBcnMXaiMEB3A2NknYf3eeKV
|
|
70
|
+
hkPNl1/BMA0GCSqGSIb3DQEBCwUAA4IBAQAfxzM4OzKzXj4vvS4ian65PHlV1YiY
|
|
71
|
+
JOonKRWzA3LDjZ0TAF1WMEXiD46yV6HYAYdeQTGin6AaL2P4Z11rCVJPQVHW6UGv
|
|
72
|
+
8AoqW4QmBer0U3dJpu28UZ7IA2KPUdAJKhukl7Y5M4fotMxydh5nmh/743GZw3g9
|
|
73
|
+
krSDY8HAFqhr2R9zo2gh42IPUQI4YJcZiU4vnZlaE9NbaJmZmCm357AJ6RhHMC66
|
|
74
|
+
WZ1O8+UD3EpkFWamhrPEU2GOLFjDDG/SOtXv7BBG0zCn/VRwShCj5kfivZWfWxvN
|
|
75
|
+
/UrJwT49JDcuuHV7P0SwabvCQurMRd7J6ANO+esgdxGavWsnzT4U3Ac2
|
|
76
|
+
-----END CERTIFICATE-----
|
|
77
|
+
-----BEGIN CERTIFICATE-----
|
|
78
|
+
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
|
|
108
|
+
-----END CERTIFICATE-----
|
|
109
|
+
-----BEGIN CERTIFICATE-----
|
|
110
|
+
MIIFYjCCBEqgAwIBAgIQd70NbNs2+RrqIQ/E8FjTDTANBgkqhkiG9w0BAQsFADBX
|
|
111
|
+
MQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEQMA4GA1UE
|
|
112
|
+
CxMHUm9vdCBDQTEbMBkGA1UEAxMSR2xvYmFsU2lnbiBSb290IENBMB4XDTIwMDYx
|
|
113
|
+
OTAwMDA0MloXDTI4MDEyODAwMDA0MlowRzELMAkGA1UEBhMCVVMxIjAgBgNVBAoT
|
|
114
|
+
GUdvb2dsZSBUcnVzdCBTZXJ2aWNlcyBMTEMxFDASBgNVBAMTC0dUUyBSb290IFIx
|
|
115
|
+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAthECix7joXebO9y/lD63
|
|
116
|
+
ladAPKH9gvl9MgaCcfb2jH/76Nu8ai6Xl6OMS/kr9rH5zoQdsfnFl97vufKj6bwS
|
|
117
|
+
iV6nqlKr+CMny6SxnGPb15l+8Ape62im9MZaRw1NEDPjTrETo8gYbEvs/AmQ351k
|
|
118
|
+
KSUjB6G00j0uYODP0gmHu81I8E3CwnqIiru6z1kZ1q+PsAewnjHxgsHA3y6mbWwZ
|
|
119
|
+
DrXYfiYaRQM9sHmklCitD38m5agI/pboPGiUU+6DOogrFZYJsuB6jC511pzrp1Zk
|
|
120
|
+
j5ZPaK49l8KEj8C8QMALXL32h7M1bKwYUH+E4EzNktMg6TO8UpmvMrUpsyUqtEj5
|
|
121
|
+
cuHKZPfmghCN6J3Cioj6OGaK/GP5Afl4/Xtcd/p2h/rs37EOeZVXtL0m79YB0esW
|
|
122
|
+
CruOC7XFxYpVq9Os6pFLKcwZpDIlTirxZUTQAs6qzkm06p98g7BAe+dDq6dso499
|
|
123
|
+
iYH6TKX/1Y7DzkvgtdizjkXPdsDtQCv9Uw+wp9U7DbGKogPeMa3Md+pvez7W35Ei
|
|
124
|
+
Eua++tgy/BBjFFFy3l3WFpO9KWgz7zpm7AeKJt8T11dleCfeXkkUAKIAf5qoIbap
|
|
125
|
+
sZWwpbkNFhHax2xIPEDgfg1azVY80ZcFuctL7TlLnMQ/0lUTbiSw1nH69MG6zO0b
|
|
126
|
+
9f6BQdgAmD06yK56mDcYBZUCAwEAAaOCATgwggE0MA4GA1UdDwEB/wQEAwIBhjAP
|
|
127
|
+
BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTkrysmcRorSCeFL1JmLO/wiRNxPjAf
|
|
128
|
+
BgNVHSMEGDAWgBRge2YaRQ2XyolQL30EzTSo//z9SzBgBggrBgEFBQcBAQRUMFIw
|
|
129
|
+
JQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnBraS5nb29nL2dzcjEwKQYIKwYBBQUH
|
|
130
|
+
MAKGHWh0dHA6Ly9wa2kuZ29vZy9nc3IxL2dzcjEuY3J0MDIGA1UdHwQrMCkwJ6Al
|
|
131
|
+
oCOGIWh0dHA6Ly9jcmwucGtpLmdvb2cvZ3NyMS9nc3IxLmNybDA7BgNVHSAENDAy
|
|
132
|
+
MAgGBmeBDAECATAIBgZngQwBAgIwDQYLKwYBBAHWeQIFAwIwDQYLKwYBBAHWeQIF
|
|
133
|
+
AwMwDQYJKoZIhvcNAQELBQADggEBADSkHrEoo9C0dhemMXoh6dFSPsjbdBZBiLg9
|
|
134
|
+
NR3t5P+T4Vxfq7vqfM/b5A3Ri1fyJm9bvhdGaJQ3b2t6yMAYN/olUazsaL+yyEn9
|
|
135
|
+
WprKASOshIArAoyZl+tJaox118fessmXn1hIVw41oeQa1v1vg4Fv74zPl6/AhSrw
|
|
136
|
+
9U5pCZEt4Wi4wStz6dTZ/CLANx8LZh1J7QJVj2fhMtfTJr9w4z30Z209fOU0iOMy
|
|
137
|
+
+qduBmpvvYuR7hZL6Dupszfnw0Skfths18dG9ZKb59UhvmaSGZRVbNQpsg3BZlvi
|
|
138
|
+
d0lIKO2d1xozclOzgjXPYovJJIultzkMu34qQb9Sz/yilrbCgj8=
|
|
139
|
+
-----END CERTIFICATE-----
|
|
140
|
+
-----BEGIN CERTIFICATE-----
|
|
141
|
+
MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
|
|
142
|
+
A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
|
|
143
|
+
b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
|
|
144
|
+
MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
|
|
145
|
+
YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
|
|
146
|
+
aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
|
|
147
|
+
jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
|
|
148
|
+
xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
|
|
149
|
+
1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
|
|
150
|
+
snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
|
|
151
|
+
U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
|
|
152
|
+
9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
|
|
153
|
+
BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
|
|
154
|
+
AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
|
|
155
|
+
yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
|
|
156
|
+
38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
|
|
157
|
+
AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
|
|
158
|
+
DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
|
|
159
|
+
HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
|
|
160
|
+
-----END CERTIFICATE-----
|
|
Binary file
|
package/test/utils.tests.js
CHANGED
|
@@ -1,11 +1,63 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
const assert = require("assert"),
|
|
2
|
+
utils = require("../lib/utils");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const {createPublicKey} = require('crypto')
|
|
5
|
+
|
|
6
|
+
describe("pemToCert", function () {
|
|
7
|
+
it("should not throw when the cert is invalid", function () {
|
|
8
|
+
var cert = utils.pemToCert('abc');
|
|
9
|
+
assert.ok(!cert);
|
|
10
|
+
});
|
|
11
11
|
});
|
|
12
|
+
|
|
13
|
+
describe("fixPemFormatting", () => {
|
|
14
|
+
it("returns the original when the original is not in PEM format", () => {
|
|
15
|
+
let originalCert = fs.readFileSync(__dirname + '/test-auth0.der');
|
|
16
|
+
let standardizedCert = utils.fixPemFormatting(originalCert);
|
|
17
|
+
assert.strictEqual(originalCert.compare(standardizedCert), 0);
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it("handles already correctly formatted PEM content", () => {
|
|
21
|
+
let originalCert = fs.readFileSync(__dirname + '/test-auth0_rsa.pub');
|
|
22
|
+
let standardizedCert = utils.fixPemFormatting(originalCert);
|
|
23
|
+
assert.notStrictEqual(originalCert, standardizedCert);
|
|
24
|
+
assert.deepStrictEqual(createPublicKey(originalCert), createPublicKey(standardizedCert));
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it("handles PEM content with extra data before the cert", () => {
|
|
28
|
+
let originalCert = Buffer.from(`data that should be ignored\n${fs.readFileSync(__dirname + '/test-auth0_rsa.pub').toString()}`)
|
|
29
|
+
let standardizedCert = utils.fixPemFormatting(originalCert);
|
|
30
|
+
assert.notStrictEqual(originalCert, standardizedCert);
|
|
31
|
+
assert.deepStrictEqual(createPublicKey(originalCert), createPublicKey(standardizedCert));
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it("handles PEM content with extra data after the cert", () => {
|
|
35
|
+
let originalCert = Buffer.from(`${fs.readFileSync(__dirname + '/test-auth0_rsa.pub').toString()}\ndata that should be ignored`)
|
|
36
|
+
let standardizedCert = utils.fixPemFormatting(originalCert);
|
|
37
|
+
assert.notStrictEqual(originalCert, standardizedCert);
|
|
38
|
+
assert.deepStrictEqual(createPublicKey(originalCert), createPublicKey(standardizedCert));
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it("handles incorrectly formatted PEM content", () => {
|
|
42
|
+
let originalCert = Buffer.from(fs.readFileSync(__dirname + '/test-auth0_rsa.pub').toString().replaceAll(/[\r\n]/g, ''));
|
|
43
|
+
let standardizedCert = utils.fixPemFormatting(originalCert);
|
|
44
|
+
assert.notStrictEqual(originalCert, standardizedCert);
|
|
45
|
+
let correctCert = createPublicKey(fs.readFileSync(__dirname + '/test-auth0_rsa.pub'))
|
|
46
|
+
assert.deepStrictEqual(correctCert, createPublicKey(standardizedCert));
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it("handles already correctly formatted PEM chains", () => {
|
|
50
|
+
let originalCert = fs.readFileSync(__dirname + '/test-auth0-chain.pem');
|
|
51
|
+
let standardizedCert = utils.fixPemFormatting(originalCert);
|
|
52
|
+
assert.notStrictEqual(originalCert, standardizedCert);
|
|
53
|
+
assert.deepStrictEqual(createPublicKey(originalCert), createPublicKey(standardizedCert));
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it("handles incorrectly formatted PEM chains", () => {
|
|
57
|
+
let originalCert = Buffer.from(fs.readFileSync(__dirname + '/test-auth0-chain.pem').toString().replaceAll(/[\r\n]/g, ''));
|
|
58
|
+
let standardizedCert = utils.fixPemFormatting(originalCert);
|
|
59
|
+
assert.notStrictEqual(originalCert, standardizedCert);
|
|
60
|
+
let correctCert = createPublicKey(fs.readFileSync(__dirname + '/test-auth0-chain.pem'))
|
|
61
|
+
assert.deepStrictEqual(correctCert, createPublicKey(standardizedCert));
|
|
62
|
+
})
|
|
63
|
+
})
|