samlify 2.8.1 → 2.8.4
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/.travis.yml +1 -2
- package/README.md +1 -1
- package/build/index.js +5 -1
- package/build/index.js.map +1 -1
- package/build/src/binding-post.js +6 -2
- package/build/src/binding-post.js.map +1 -1
- package/build/src/binding-redirect.js +8 -2
- package/build/src/binding-redirect.js.map +1 -1
- package/build/src/binding-simplesign.js +6 -2
- package/build/src/binding-simplesign.js.map +1 -1
- package/build/src/entity-idp.js +1 -3
- package/build/src/entity-idp.js.map +1 -1
- package/build/src/entity-sp.js +1 -3
- package/build/src/entity-sp.js.map +1 -1
- package/build/src/entity.js +6 -2
- package/build/src/entity.js.map +1 -1
- package/build/src/extractor.js +11 -11
- package/build/src/extractor.js.map +1 -1
- package/build/src/flow.js +1 -1
- package/build/src/flow.js.map +1 -1
- package/build/src/libsaml.js +25 -24
- package/build/src/libsaml.js.map +1 -1
- package/build/src/metadata-idp.js +3 -24
- package/build/src/metadata-idp.js.map +1 -1
- package/build/src/metadata-sp.js +3 -24
- package/build/src/metadata-sp.js.map +1 -1
- package/build/src/metadata.js +5 -1
- package/build/src/metadata.js.map +1 -1
- package/build/src/utility.js +2 -2
- package/build/src/utility.js.map +1 -1
- package/package.json +11 -10
- package/src/binding-post.ts +1 -1
- package/src/binding-redirect.ts +13 -2
- package/src/binding-simplesign.ts +7 -1
- package/src/entity.ts +1 -1
- package/src/libsaml.ts +58 -41
- package/src/metadata-idp.ts +1 -1
- package/src/metadata-sp.ts +1 -1
- package/types/src/libsaml.d.ts +3 -3
package/src/libsaml.ts
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
import { DOMParser } from '@xmldom/xmldom';
|
|
8
8
|
import utility, { flattenDeep, isString } from './utility';
|
|
9
9
|
import { algorithms, wording, namespace } from './urn';
|
|
10
|
-
import { select
|
|
10
|
+
import { select } from 'xpath';
|
|
11
11
|
import { MetadataInterface } from './metadata';
|
|
12
|
-
import
|
|
12
|
+
import nrsa, { SigningSchemeHash } from 'node-rsa';
|
|
13
13
|
import { SignedXml, FileKeyInfo } from 'xml-crypto';
|
|
14
14
|
import * as xmlenc from '@authenio/xml-encryption';
|
|
15
15
|
import { extract } from './extractor';
|
|
@@ -60,7 +60,7 @@ export interface LoginResponseAttribute {
|
|
|
60
60
|
|
|
61
61
|
export interface LoginResponseAdditionalTemplates {
|
|
62
62
|
attributeStatementTemplate?: AttributeStatementTemplate;
|
|
63
|
-
attributeTemplate?:AttributeTemplate;
|
|
63
|
+
attributeTemplate?: AttributeTemplate;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
export interface BaseSamlTemplate {
|
|
@@ -91,7 +91,7 @@ export interface LibSamlInterface {
|
|
|
91
91
|
getQueryParamByType: (type: string) => string;
|
|
92
92
|
createXPath: (local, isExtractAll?: boolean) => string;
|
|
93
93
|
replaceTagsByValue: (rawXML: string, tagValues: any) => string;
|
|
94
|
-
attributeStatementBuilder: (attributes: LoginResponseAttribute[], attributeTemplate
|
|
94
|
+
attributeStatementBuilder: (attributes: LoginResponseAttribute[], attributeTemplate: AttributeTemplate, attributeStatementTemplate: AttributeStatementTemplate) => string;
|
|
95
95
|
constructSAMLSignature: (opts: SignatureConstructor) => string;
|
|
96
96
|
verifySignature: (xml: string, opts) => [boolean, any];
|
|
97
97
|
createKeySection: (use: KeyUse, cert: string | Buffer) => {};
|
|
@@ -132,9 +132,9 @@ const libSaml = () => {
|
|
|
132
132
|
*
|
|
133
133
|
*/
|
|
134
134
|
const nrsaAliasMapping = {
|
|
135
|
-
'http://www.w3.org/2000/09/xmldsig#rsa-sha1': 'sha1',
|
|
136
|
-
'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256': 'sha256',
|
|
137
|
-
'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512': 'sha512',
|
|
135
|
+
'http://www.w3.org/2000/09/xmldsig#rsa-sha1': 'pkcs1-sha1',
|
|
136
|
+
'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256': 'pkcs1-sha256',
|
|
137
|
+
'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512': 'pkcs1-sha512',
|
|
138
138
|
};
|
|
139
139
|
/**
|
|
140
140
|
* @desc Default login request template
|
|
@@ -164,7 +164,7 @@ const libSaml = () => {
|
|
|
164
164
|
* @type {AttributeTemplate}
|
|
165
165
|
*/
|
|
166
166
|
const defaultAttributeTemplate = {
|
|
167
|
-
context: '<saml:Attribute Name="{Name}" NameFormat="{NameFormat}"><AttributeValue xmlns:xs="{ValueXmlnsXs}" xmlns:xsi="{ValueXmlnsXsi}" xsi:type="{ValueXsiType}">{Value}</AttributeValue></Attribute>',
|
|
167
|
+
context: '<saml:Attribute Name="{Name}" NameFormat="{NameFormat}"><saml:AttributeValue xmlns:xs="{ValueXmlnsXs}" xmlns:xsi="{ValueXmlnsXsi}" xsi:type="{ValueXsiType}">{Value}</saml:AttributeValue></saml:Attribute>',
|
|
168
168
|
};
|
|
169
169
|
|
|
170
170
|
/**
|
|
@@ -174,7 +174,7 @@ const libSaml = () => {
|
|
|
174
174
|
const defaultLoginResponseTemplate = {
|
|
175
175
|
context: '<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="{ID}" Version="2.0" IssueInstant="{IssueInstant}" Destination="{Destination}" InResponseTo="{InResponseTo}"><saml:Issuer>{Issuer}</saml:Issuer><samlp:Status><samlp:StatusCode Value="{StatusCode}"/></samlp:Status><saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="{AssertionID}" Version="2.0" IssueInstant="{IssueInstant}"><saml:Issuer>{Issuer}</saml:Issuer><saml:Subject><saml:NameID Format="{NameIDFormat}">{NameID}</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData NotOnOrAfter="{SubjectConfirmationDataNotOnOrAfter}" Recipient="{SubjectRecipient}" InResponseTo="{InResponseTo}"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="{ConditionsNotBefore}" NotOnOrAfter="{ConditionsNotOnOrAfter}"><saml:AudienceRestriction><saml:Audience>{Audience}</saml:Audience></saml:AudienceRestriction></saml:Conditions>{AuthnStatement}{AttributeStatement}</saml:Assertion></samlp:Response>',
|
|
176
176
|
attributes: [],
|
|
177
|
-
additionalTemplates:{
|
|
177
|
+
additionalTemplates: {
|
|
178
178
|
"attributeStatementTemplate": defaultAttributeStatementTemplate,
|
|
179
179
|
"attributeTemplate": defaultAttributeTemplate
|
|
180
180
|
}
|
|
@@ -192,14 +192,14 @@ const libSaml = () => {
|
|
|
192
192
|
* @param {string} sigAlg signature algorithm
|
|
193
193
|
* @return {string/null} signing algorithm short-hand for the module node-rsa
|
|
194
194
|
*/
|
|
195
|
-
function getSigningScheme(sigAlg?: string):
|
|
195
|
+
function getSigningScheme(sigAlg?: string): SigningSchemeHash {
|
|
196
196
|
if (sigAlg) {
|
|
197
197
|
const algAlias = nrsaAliasMapping[sigAlg];
|
|
198
198
|
if (!(algAlias === undefined)) {
|
|
199
199
|
return algAlias;
|
|
200
200
|
}
|
|
201
201
|
}
|
|
202
|
-
return nrsaAliasMapping[signatureAlgorithms.RSA_SHA1];
|
|
202
|
+
return nrsaAliasMapping[signatureAlgorithms.RSA_SHA1];
|
|
203
203
|
}
|
|
204
204
|
/**
|
|
205
205
|
* @private
|
|
@@ -270,27 +270,25 @@ const libSaml = () => {
|
|
|
270
270
|
* @param {AttributeStatementTemplate} attributeStatementTemplate the attributStatement tag template to be used
|
|
271
271
|
* @return {string}
|
|
272
272
|
*/
|
|
273
|
-
attributeStatementBuilder(
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
return
|
|
291
|
-
}
|
|
292
|
-
return attributeStatementTemplate.context.replace('{Attributes}',attr);
|
|
293
|
-
},
|
|
273
|
+
attributeStatementBuilder(
|
|
274
|
+
attributes: LoginResponseAttribute[],
|
|
275
|
+
attributeTemplate: AttributeTemplate = defaultAttributeTemplate,
|
|
276
|
+
attributeStatementTemplate: AttributeStatementTemplate = defaultAttributeStatementTemplate
|
|
277
|
+
): string {
|
|
278
|
+
const attr = attributes.map(({ name, nameFormat, valueTag, valueXsiType, valueXmlnsXs, valueXmlnsXsi }) => {
|
|
279
|
+
const defaultValueXmlnsXs = 'http://www.w3.org/2001/XMLSchema';
|
|
280
|
+
const defaultValueXmlnsXsi = 'http://www.w3.org/2001/XMLSchema-instance';
|
|
281
|
+
let attributeLine = attributeTemplate.context;
|
|
282
|
+
attributeLine = attributeLine.replace('{Name}', name);
|
|
283
|
+
attributeLine = attributeLine.replace('{NameFormat}', nameFormat);
|
|
284
|
+
attributeLine = attributeLine.replace('{ValueXmlnsXs}', valueXmlnsXs ? valueXmlnsXs : defaultValueXmlnsXs);
|
|
285
|
+
attributeLine = attributeLine.replace('{ValueXmlnsXsi}', valueXmlnsXsi ? valueXmlnsXsi : defaultValueXmlnsXsi);
|
|
286
|
+
attributeLine = attributeLine.replace('{ValueXsiType}', valueXsiType);
|
|
287
|
+
attributeLine = attributeLine.replace('{Value}', `{${tagging('attr', valueTag)}}`);
|
|
288
|
+
return attributeLine;
|
|
289
|
+
}).join('');
|
|
290
|
+
return attributeStatementTemplate.context.replace('{Attributes}', attr);
|
|
291
|
+
},
|
|
294
292
|
|
|
295
293
|
/**
|
|
296
294
|
* @desc Construct the XML signature for POST binding
|
|
@@ -537,12 +535,22 @@ const libSaml = () => {
|
|
|
537
535
|
* @param {string} signingAlgorithm signing algorithm
|
|
538
536
|
* @return {string} message signature
|
|
539
537
|
*/
|
|
540
|
-
constructMessageSignature(
|
|
538
|
+
constructMessageSignature(
|
|
539
|
+
octetString: string,
|
|
540
|
+
key: string,
|
|
541
|
+
passphrase?: string,
|
|
542
|
+
isBase64?: boolean,
|
|
543
|
+
signingAlgorithm?: string
|
|
544
|
+
) {
|
|
541
545
|
// Default returning base64 encoded signature
|
|
542
546
|
// Embed with node-rsa module
|
|
543
|
-
const decryptedKey = new nrsa(
|
|
544
|
-
|
|
545
|
-
|
|
547
|
+
const decryptedKey = new nrsa(
|
|
548
|
+
utility.readPrivateKey(key, passphrase),
|
|
549
|
+
'private',
|
|
550
|
+
{
|
|
551
|
+
signingScheme: getSigningScheme(signingAlgorithm),
|
|
552
|
+
}
|
|
553
|
+
);
|
|
546
554
|
const signature = decryptedKey.sign(octetString);
|
|
547
555
|
// Use private key to sign data
|
|
548
556
|
return isBase64 !== false ? signature.toString('base64') : signature;
|
|
@@ -555,11 +563,16 @@ const libSaml = () => {
|
|
|
555
563
|
* @param {string} verifyAlgorithm algorithm used to verify
|
|
556
564
|
* @return {boolean} verification result
|
|
557
565
|
*/
|
|
558
|
-
verifyMessageSignature(
|
|
566
|
+
verifyMessageSignature(
|
|
567
|
+
metadata,
|
|
568
|
+
octetString: string,
|
|
569
|
+
signature: string | Buffer,
|
|
570
|
+
verifyAlgorithm?: string
|
|
571
|
+
) {
|
|
559
572
|
const signCert = metadata.getX509Certificate(certUse.signing);
|
|
560
573
|
const signingScheme = getSigningScheme(verifyAlgorithm);
|
|
561
|
-
const key = new nrsa(utility.getPublicKeyPemFromCertificate(signCert), { signingScheme });
|
|
562
|
-
return key.verify(
|
|
574
|
+
const key = new nrsa(utility.getPublicKeyPemFromCertificate(signCert), 'public', { signingScheme });
|
|
575
|
+
return key.verify(Buffer.from(octetString), Buffer.from(signature));
|
|
563
576
|
},
|
|
564
577
|
/**
|
|
565
578
|
* @desc Get the public key in string format
|
|
@@ -600,12 +613,16 @@ const libSaml = () => {
|
|
|
600
613
|
if (assertions.length !== 1) {
|
|
601
614
|
throw new Error('ERR_MULTIPLE_ASSERTION');
|
|
602
615
|
}
|
|
616
|
+
|
|
603
617
|
// Perform encryption depends on the setting, default is false
|
|
604
618
|
if (sourceEntitySetting.isAssertionEncrypted) {
|
|
619
|
+
|
|
620
|
+
const publicKeyPem = utility.getPublicKeyPemFromCertificate(targetEntityMetadata.getX509Certificate(certUse.encrypt));
|
|
621
|
+
|
|
605
622
|
xmlenc.encrypt(assertions[0].toString(), {
|
|
606
623
|
// use xml-encryption module
|
|
607
|
-
rsa_pub: Buffer.from(
|
|
608
|
-
pem: Buffer.from(
|
|
624
|
+
rsa_pub: Buffer.from(publicKeyPem), // public key from certificate
|
|
625
|
+
pem: Buffer.from(`-----BEGIN CERTIFICATE-----${targetEntityMetadata.getX509Certificate(certUse.encrypt)}-----END CERTIFICATE-----`),
|
|
609
626
|
encryptionAlgorithm: sourceEntitySetting.dataEncryptionAlgorithm,
|
|
610
627
|
keyEncryptionAlgorithm: sourceEntitySetting.keyEncryptionAlgorithm,
|
|
611
628
|
}, (err, res) => {
|
package/src/metadata-idp.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { MetadataIdpOptions, MetadataIdpConstructor } from './types';
|
|
|
8
8
|
import { namespace } from './urn';
|
|
9
9
|
import libsaml from './libsaml';
|
|
10
10
|
import { isNonEmptyArray, isString } from './utility';
|
|
11
|
-
import
|
|
11
|
+
import xml from 'xml';
|
|
12
12
|
|
|
13
13
|
export interface IdpMetadataInterface extends MetadataInterface {
|
|
14
14
|
|
package/src/metadata-sp.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { MetadataSpConstructor, MetadataSpOptions } from './types';
|
|
|
8
8
|
import { namespace, elementsOrder as order } from './urn';
|
|
9
9
|
import libsaml from './libsaml';
|
|
10
10
|
import { isNonEmptyArray, isString } from './utility';
|
|
11
|
-
import
|
|
11
|
+
import xml from 'xml';
|
|
12
12
|
|
|
13
13
|
export interface SpMetadataInterface extends MetadataInterface {
|
|
14
14
|
|
package/types/src/libsaml.d.ts
CHANGED
|
@@ -129,7 +129,7 @@ declare const _default: {
|
|
|
129
129
|
* @param {AttributeStatementTemplate} attributeStatementTemplate the attributStatement tag template to be used
|
|
130
130
|
* @return {string}
|
|
131
131
|
*/
|
|
132
|
-
attributeStatementBuilder(attributes: LoginResponseAttribute[], attributeTemplate
|
|
132
|
+
attributeStatementBuilder(attributes: LoginResponseAttribute[], attributeTemplate?: AttributeTemplate, attributeStatementTemplate?: AttributeStatementTemplate): string;
|
|
133
133
|
/**
|
|
134
134
|
* @desc Construct the XML signature for POST binding
|
|
135
135
|
* @param {string} rawSamlMessage request/response xml string
|
|
@@ -165,7 +165,7 @@ declare const _default: {
|
|
|
165
165
|
* @param {string} signingAlgorithm signing algorithm
|
|
166
166
|
* @return {string} message signature
|
|
167
167
|
*/
|
|
168
|
-
constructMessageSignature(octetString: string, key: string, passphrase?: string | undefined, isBase64?: boolean | undefined, signingAlgorithm?: string | undefined):
|
|
168
|
+
constructMessageSignature(octetString: string, key: string, passphrase?: string | undefined, isBase64?: boolean | undefined, signingAlgorithm?: string | undefined): string | Buffer;
|
|
169
169
|
/**
|
|
170
170
|
* @desc Verifies message signature
|
|
171
171
|
* @param {Metadata} metadata metadata object of identity provider or service provider
|
|
@@ -174,7 +174,7 @@ declare const _default: {
|
|
|
174
174
|
* @param {string} verifyAlgorithm algorithm used to verify
|
|
175
175
|
* @return {boolean} verification result
|
|
176
176
|
*/
|
|
177
|
-
verifyMessageSignature(metadata: any, octetString: string, signature: string | Buffer, verifyAlgorithm?: string | undefined):
|
|
177
|
+
verifyMessageSignature(metadata: any, octetString: string, signature: string | Buffer, verifyAlgorithm?: string | undefined): boolean;
|
|
178
178
|
/**
|
|
179
179
|
* @desc Get the public key in string format
|
|
180
180
|
* @param {string} x509Certificate certificate
|