├── .eslintignore ├── .npmignore ├── .prettierrc.json ├── .markdownlint.json ├── test ├── static │ ├── hmac.key │ ├── hmac-foobar.key │ ├── client_public.der │ ├── saml_external_ns.pem │ ├── client_public.pem │ ├── valid_signature_without_transforms_element.xml │ ├── invalid_signature_without_transforms_element.xml │ ├── hmac_signature.xml │ ├── integration │ │ ├── expectedVerifyComplex.xml │ │ └── expectedVerify.xml │ ├── client.pem │ ├── empty_uri.pem │ ├── feide_public.pem │ ├── signature_with_inclusivenamespaces.pem │ ├── wsfederation_metadata.pem │ ├── invalid_signature - hash.xml │ ├── invalid_signature - signature value.xml │ ├── invalid_signature - non existing reference.xml │ ├── valid_signature.xml │ ├── valid_signature_with_whitespace_in_digestvalue.xml │ ├── invalid_signature - changed content.xml │ ├── valid_signature_with_lowercase_id_attribute.xml │ ├── keyinfo.pem │ ├── windows_store_certificate.pem │ ├── valid_signature_with_root_level_sig_namespace.xml │ ├── valid_signature wsu.xml │ ├── invalid_signature - wsu - hash.xml │ ├── valid_signature_with_reference_keyInfo.xml │ ├── invalid_signature - wsu - changed content.xml │ ├── invalid_signature - wsu - invalid signature value.xml │ ├── invalid_signature - wsu - non existing reference.xml │ ├── windows_store_signature.xml │ ├── idp_certificate.pem │ ├── unsigned_saml_response.xml │ ├── id_with_quotes.xml │ ├── valid_signature_utf8.xml │ ├── idp_private_key.pem │ ├── signature_with_inclusivenamespaces.xml │ ├── signature_with_inclusivenamespaces_lines.xml │ ├── signature_with_inclusivenamespaces_lines_windows.xml │ ├── client_bundle.pem │ ├── valid_signature_with_unused_prefixes.xml │ ├── saml_external_ns.xml │ ├── keyinfo - pretty-printed.xml │ ├── valid_saml_sha256_rsa_mgf1.xml │ ├── invalid_saml_sha256_rsa_mgf1.xml │ ├── valid_saml_with_digest_comment.xml │ ├── invalid_saml_no_signed_info.xml │ ├── valid_saml.xml │ ├── valid_saml_withcomments.xml │ ├── valid_saml_signature_wrapping.xml │ └── saml_wrapped_signed_info_node.xml ├── validators │ ├── XmlCryptoUtilities │ │ ├── XmlCryptoUtilities │ │ │ ├── bin │ │ │ │ └── Debug │ │ │ │ │ ├── Example.xml │ │ │ │ │ ├── ClientPrivate.pfx │ │ │ │ │ ├── XmlCryptoUtilities.exe │ │ │ │ │ ├── XmlCryptoUtilities.pdb │ │ │ │ │ ├── XmlCryptoUtilities.vshost.exe │ │ │ │ │ ├── XmlCryptoUtilities.vshost.exe.manifest │ │ │ │ │ └── signedExample.xml │ │ │ ├── obj │ │ │ │ └── x86 │ │ │ │ │ └── Debug │ │ │ │ │ ├── XmlCryptoUtilities.exe │ │ │ │ │ ├── XmlCryptoUtilities.pdb │ │ │ │ │ ├── DesignTimeResolveAssemblyReferencesInput.cache │ │ │ │ │ └── ValidateSignature.csproj.FileListAbsolute.txt │ │ │ ├── Properties │ │ │ │ └── AssemblyInfo.cs │ │ │ ├── ValidateSignature.csproj │ │ │ ├── utilities.cs │ │ │ └── Program.cs │ │ ├── XmlCryptoUtilities.suo │ │ └── XmlCryptoUtilities.sln │ └── XmlCryptoJava │ │ ├── src │ │ └── test │ │ │ ├── resources │ │ │ └── log4j.xml │ │ │ └── java │ │ │ └── org │ │ │ └── nodejs │ │ │ └── xmlcrypto │ │ │ └── HMACTest.java │ │ └── pom.xml ├── wsfed-metadata-tests.spec.ts ├── key-info-tests.spec.ts ├── hmac-tests.spec.ts ├── utils-tests.spec.ts └── document-tests.spec.ts ├── tsconfig.eslint.json ├── .nycrc.json ├── .release-it.json ├── .prettierignore ├── .gitignore ├── .mocharc.json ├── src ├── index.ts ├── hash-algorithms.ts ├── enveloped-signature.ts └── signature-algorithms.ts ├── .vscode └── settings.json ├── .gitattributes ├── example ├── client_public.pem ├── client.pem └── example.js ├── .github ├── dependabot.yml └── workflows │ ├── ci.yml │ └── codeql-analysis.yml ├── .eslintrc.json ├── LICENSE ├── .grenrc.js ├── package.json └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | example/ -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100 3 | } 4 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "MD013": false, 3 | "MD024": false 4 | } 5 | -------------------------------------------------------------------------------- /test/static/hmac.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-saml/xml-crypto/HEAD/test/static/hmac.key -------------------------------------------------------------------------------- /test/static/hmac-foobar.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-saml/xml-crypto/HEAD/test/static/hmac-foobar.key -------------------------------------------------------------------------------- /test/static/client_public.der: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-saml/xml-crypto/HEAD/test/static/client_public.der -------------------------------------------------------------------------------- /tsconfig.eslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": [], 4 | "include": ["test", "src"] 5 | } 6 | -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/bin/Debug/Example.xml: -------------------------------------------------------------------------------- 1 | Example text to be signed. -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-saml/xml-crypto/HEAD/test/validators/XmlCryptoUtilities/XmlCryptoUtilities.suo -------------------------------------------------------------------------------- /.nycrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@istanbuljs/nyc-config-typescript", 3 | "all": true, 4 | "check-coverage": false, 5 | "reporter": ["lcov", "text"], 6 | "include": ["src"] 7 | } 8 | -------------------------------------------------------------------------------- /.release-it.json: -------------------------------------------------------------------------------- 1 | { 2 | "github": { 3 | "release": true, 4 | "releaseName": "v${version}" 5 | }, 6 | "hooks": { 7 | "after:bump": "npm run changelog" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore artifacts: 2 | lib 3 | node_modules 4 | package-lock.json 5 | .eslintcache 6 | .prettierignore 7 | test/static/* 8 | test/validators/* 9 | .nyc_output/* 10 | coverage/* 11 | -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/bin/Debug/ClientPrivate.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-saml/xml-crypto/HEAD/test/validators/XmlCryptoUtilities/XmlCryptoUtilities/bin/Debug/ClientPrivate.pfx -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/bin/Debug/XmlCryptoUtilities.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-saml/xml-crypto/HEAD/test/validators/XmlCryptoUtilities/XmlCryptoUtilities/bin/Debug/XmlCryptoUtilities.exe -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/bin/Debug/XmlCryptoUtilities.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-saml/xml-crypto/HEAD/test/validators/XmlCryptoUtilities/XmlCryptoUtilities/bin/Debug/XmlCryptoUtilities.pdb -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | lib/ 2 | node_modules/ 3 | p.js 4 | p.txt 5 | *.svclog 6 | .DS_Store 7 | *.*~ 8 | *.swp 9 | npm-debug.log 10 | /test/validators/XmlCryptoJava/target/ 11 | .eslintcache 12 | .nyc_output/ 13 | coverage/ 14 | .idea 15 | -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/obj/x86/Debug/XmlCryptoUtilities.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-saml/xml-crypto/HEAD/test/validators/XmlCryptoUtilities/XmlCryptoUtilities/obj/x86/Debug/XmlCryptoUtilities.exe -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/obj/x86/Debug/XmlCryptoUtilities.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-saml/xml-crypto/HEAD/test/validators/XmlCryptoUtilities/XmlCryptoUtilities/obj/x86/Debug/XmlCryptoUtilities.pdb -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/bin/Debug/XmlCryptoUtilities.vshost.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-saml/xml-crypto/HEAD/test/validators/XmlCryptoUtilities/XmlCryptoUtilities/bin/Debug/XmlCryptoUtilities.vshost.exe -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/obj/x86/Debug/DesignTimeResolveAssemblyReferencesInput.cache: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/node-saml/xml-crypto/HEAD/test/validators/XmlCryptoUtilities/XmlCryptoUtilities/obj/x86/Debug/DesignTimeResolveAssemblyReferencesInput.cache -------------------------------------------------------------------------------- /.mocharc.json: -------------------------------------------------------------------------------- 1 | { 2 | "diff": true, 3 | "extension": "spec.ts", 4 | "package": "./package.json", 5 | "recursive": true, 6 | "reporter": "spec", 7 | "require": ["choma", "ts-node/register"], 8 | "spec": "test/*.spec.ts", 9 | "watch-files": "test/*.spec.ts", 10 | "colors": true 11 | } 12 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { C14nCanonicalization, C14nCanonicalizationWithComments } from "./c14n-canonicalization"; 2 | export { 3 | ExclusiveCanonicalization, 4 | ExclusiveCanonicalizationWithComments, 5 | } from "./exclusive-canonicalization"; 6 | export { SignedXml } from "./signed-xml"; 7 | export * from "./types"; 8 | export * from "./utils"; 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "Canonicalization", 4 | "canonicalize", 5 | "canonicalized", 6 | "codecov", 7 | "feide", 8 | "HMAC", 9 | "posteb", 10 | "preeb", 11 | "reserialization", 12 | "stricttextualmsg", 13 | "wsfederation", 14 | "wssecurity", 15 | "xades" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Git to autodetect text files and normalise their line endings to LF when they are checked into your repository. 2 | * text=auto 3 | 4 | # git won't try to convert this files 5 | *.pem -text 6 | *.der -text 7 | test/static/**/*.xml -text 8 | 9 | # These files are text and should be normalized (Convert crlf => lf) 10 | *.gitattributes text 11 | .gitignore text -------------------------------------------------------------------------------- /test/static/saml_external_ns.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PUBLIC KEY----- 2 | MIIBCgKCAQEAoXoc7IFZQRv+SwJ15zjIl9touwY5e6b7H4vn3OtOUByjOKHUX8VX 3 | 0TpbAV2ctZE2GSALx1AGuQAv6O4MVUH+qn/2IAiBY3a7zKN07UBsya7xFMQVHuGE 4 | 6EiBAs9jpA9wjvYMPRkS5wYZcwjpTQSZK7zFPPtobG8K/1vDbm/tWZjNLmZmQePm 5 | XpwrQAuC0+NlzlmnjoQYB2xp2NaTUK9JnnmuB5qev3dpUwlYGSJpf+HUIoxuo8Ip 6 | xAXOymq1d6tEEJgU1kR2sa7o1sSRFo31YeW/qYCP/gcLJZo3MRUDFe0g5MHeliFu 7 | e9DsKYUsC6qwAD3gc+MI47buiD6Msu11cwIDAQAB 8 | -----END RSA PUBLIC KEY----- 9 | -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/bin/Debug/XmlCryptoUtilities.vshost.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /example/client_public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAW 3 | MRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEy 4 | MzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqG 5 | SIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPd 6 | Vu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9x 7 | O3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8juf 8 | z2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEU 9 | MBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcN 10 | AQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5 11 | sT/txBnVJGziyO8DPYdu2fPMER8ajJfl 12 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /test/static/client_public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAW 3 | MRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEy 4 | MzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqG 5 | SIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPd 6 | Vu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9x 7 | O3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8juf 8 | z2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEU 9 | MBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcN 10 | AQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5 11 | sT/txBnVJGziyO8DPYdu2fPMER8ajJfl 12 | -----END CERTIFICATE----- 13 | -------------------------------------------------------------------------------- /test/static/valid_signature_without_transforms_element.xml: -------------------------------------------------------------------------------- 1 | 2 | some textLsMoqo1d6Sqh8DKLp00MK0fSBDA=OR1SYcyU18qELj+3DX/bW/r5DqueuyPAnNFEh3hNKFaj8ZKLB/mdsR9w8GDBCmZ2 3 | lsCTEvJqWC37oF8rm2eBSonNbdBnA+TM6Y22C8rffVzaoM3zpNoeWMH2LwFmpdKB 4 | UXOMWVExEaz/s4fOcyv1ajVuk42I3nl0xcD95+i7PjY= -------------------------------------------------------------------------------- /test/validators/XmlCryptoJava/src/test/resources/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test/static/invalid_signature_without_transforms_element.xml: -------------------------------------------------------------------------------- 1 | 2 | some tampered textLsMoqo1d6Sqh8DKLp00MK0fSBDA=OR1SYcyU18qELj+3DX/bW/r5DqueuyPAnNFEh3hNKFaj8ZKLB/mdsR9w8GDBCmZ2 3 | lsCTEvJqWC37oF8rm2eBSonNbdBnA+TM6Y22C8rffVzaoM3zpNoeWMH2LwFmpdKB 4 | UXOMWVExEaz/s4fOcyv1ajVuk42I3nl0xcD95+i7PjY= -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/obj/x86/Debug/ValidateSignature.csproj.FileListAbsolute.txt: -------------------------------------------------------------------------------- 1 | C:\Users\naveh\Documents\features\projects\xml-crypto\test\validators\XmlCryptoUtilities\XmlCryptoUtilities\bin\Debug\XmlCryptoUtilities.exe 2 | C:\Users\naveh\Documents\features\projects\xml-crypto\test\validators\XmlCryptoUtilities\XmlCryptoUtilities\bin\Debug\XmlCryptoUtilities.pdb 3 | C:\Users\naveh\Documents\features\projects\xml-crypto\test\validators\XmlCryptoUtilities\XmlCryptoUtilities\obj\x86\Debug\ResolveAssemblyReference.cache 4 | C:\Users\naveh\Documents\features\projects\xml-crypto\test\validators\XmlCryptoUtilities\XmlCryptoUtilities\obj\x86\Debug\XmlCryptoUtilities.exe 5 | C:\Users\naveh\Documents\features\projects\xml-crypto\test\validators\XmlCryptoUtilities\XmlCryptoUtilities\obj\x86\Debug\XmlCryptoUtilities.pdb 6 | -------------------------------------------------------------------------------- /test/static/hmac_signature.xml: -------------------------------------------------------------------------------- 1 | 8ZvjCBK4twpNullktn5R4thOSezHWxuouNf6siHYJ1E=EEX7i+HCAfEELjwwKP1vKyPrW10=some-key-name -------------------------------------------------------------------------------- /test/static/integration/expectedVerifyComplex.xml: -------------------------------------------------------------------------------- 1 | Harry PotterJoanne KRowlingVXkWV6BNrUKqdmwcxhIgRa86HUI=Y71mpTZ0Ba5qED2TxHLp34tq8Pa9X41M5PuABwPq7r2GaL5Ib28ELkhMtnZuZboO50bxh/9fwK6DPApP92zUuOTZi4htlPcGJRP5kvHznbwzvq7aO5FWAcpUTX+yMrlERIutiJi7mjChX+mIKF5/4DK66JfIlY5vlq61TX2gaJw= -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "npm" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "monthly" 12 | # Always increase the version requirement 13 | # to match the new version. 14 | versioning-strategy: increase 15 | - package-ecosystem: "github-actions" # See documentation for possible values 16 | directory: "/" # Location of package manifests 17 | schedule: 18 | interval: "monthly" 19 | -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/bin/Debug/signedExample.xml: -------------------------------------------------------------------------------- 1 | Harry PotterJoanne KRowlingVXkWV6BNrUKqdmwcxhIgRa86HUI=Y71mpTZ0Ba5qED2TxHLp34tq8Pa9X41M5PuABwPq7r2GaL5Ib28ELkhMtnZuZboO50bxh/9fwK6DPApP92zUuOTZi4htlPcGJRP5kvHznbwzvq7aO5FWAcpUTX+yMrlERIutiJi7mjChX+mIKF5/4DK66JfIlY5vlq61TX2gaJw= -------------------------------------------------------------------------------- /example/client.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL4vpoH3H3byehjj 3 | 7RAGxefGRATiq4mXtzc9Q91W7uT0DTaFEbjzVch9aGsNjmLs4QHsoZbuoUmi0st4 4 | x5z9SQpTAKC/dW8muzacT3E7dJJYh03MAO6RiH4LG34VRTq1SQN6qDt2rCK85eG4 5 | 5NHI4jceptZNu6Zot1zyO5/PYuFpAgMBAAECgYAhspeyF3M/xB7WIixy1oBiXMLY 6 | isESFAumgfhwU2LotkVRD6rgNl1QtMe3kCNWa9pCWQcYkxeI0IzA+JmFu2shVvoR 7 | oL7eV4VCe1Af33z24E46+cY5grxNhHt/LyCnZKcitvCcrzXExUc5n6KngX0mMKgk 8 | W7skZDwsnKzhyUV8wQJBAN2bQMeASQVOqdfqBdFgC/NPnKY2cuDi6h659QN1l+kg 9 | X3ywdZ7KKftJo1G9l45SN9YpkyEd9zEO6PMFaufJvZUCQQDbtAWxk0i8BT3UTNWC 10 | T/9bUQROPcGZagwwnRFByX7gpmfkf1ImIvbWVXSpX68/IjbjSkTw1nj/Yj1NwFZ0 11 | nxeFAkEAzPhRpXVBlPgaXkvlz7AfvY+wW4hXHyyi0YK8XdPBi25XA5SPZiylQfjt 12 | Z6iN6qSfYqYXoPT/c0/QJR+orvVJNQJBANhRPNXljVTK2GDCseoXd/ZiI5ohxg+W 13 | UaA/1fDvQsRQM7TQA4NXI7BO/YmSk4rW1jIeOxjiIspY4MFAIh+7UL0CQFL6zTg6 14 | wfeMlEZzvgqwCGoLuvTnqtvyg45z7pfcrg2cHdgCXIy9kErcjwGiu6BOevEA1qTW 15 | Rk+bv0tknWvcz/s= 16 | -----END PRIVATE KEY----- -------------------------------------------------------------------------------- /test/static/client.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAL4vpoH3H3byehjj 3 | 7RAGxefGRATiq4mXtzc9Q91W7uT0DTaFEbjzVch9aGsNjmLs4QHsoZbuoUmi0st4 4 | x5z9SQpTAKC/dW8muzacT3E7dJJYh03MAO6RiH4LG34VRTq1SQN6qDt2rCK85eG4 5 | 5NHI4jceptZNu6Zot1zyO5/PYuFpAgMBAAECgYAhspeyF3M/xB7WIixy1oBiXMLY 6 | isESFAumgfhwU2LotkVRD6rgNl1QtMe3kCNWa9pCWQcYkxeI0IzA+JmFu2shVvoR 7 | oL7eV4VCe1Af33z24E46+cY5grxNhHt/LyCnZKcitvCcrzXExUc5n6KngX0mMKgk 8 | W7skZDwsnKzhyUV8wQJBAN2bQMeASQVOqdfqBdFgC/NPnKY2cuDi6h659QN1l+kg 9 | X3ywdZ7KKftJo1G9l45SN9YpkyEd9zEO6PMFaufJvZUCQQDbtAWxk0i8BT3UTNWC 10 | T/9bUQROPcGZagwwnRFByX7gpmfkf1ImIvbWVXSpX68/IjbjSkTw1nj/Yj1NwFZ0 11 | nxeFAkEAzPhRpXVBlPgaXkvlz7AfvY+wW4hXHyyi0YK8XdPBi25XA5SPZiylQfjt 12 | Z6iN6qSfYqYXoPT/c0/QJR+orvVJNQJBANhRPNXljVTK2GDCseoXd/ZiI5ohxg+W 13 | UaA/1fDvQsRQM7TQA4NXI7BO/YmSk4rW1jIeOxjiIspY4MFAIh+7UL0CQFL6zTg6 14 | wfeMlEZzvgqwCGoLuvTnqtvyg45z7pfcrg2cHdgCXIy9kErcjwGiu6BOevEA1qTW 15 | Rk+bv0tknWvcz/s= 16 | -----END PRIVATE KEY----- -------------------------------------------------------------------------------- /test/static/empty_uri.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICcTCCAVmgAwIBAgIBATANBgkqhkiG9w0BAQQFADA+MQswCQYDVQQGEwJFUzEbMBkGA1UEChMS 3 | U2N5dGwgVU5JVCBURVNUIENBMRIwEAYDVQQLEwlVTklUIFRFU1QwHhcNMDYwMzAyMTEwOTEyWhcN 4 | MzAwNDA2MTEwOTEyWjA+MQswCQYDVQQGEwJFUzEbMBkGA1UEChMSU2N5dGwgVU5JVCBURVNUIENB 5 | MRIwEAYDVQQLEwlVTklUIFRFU1QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALfqpJyXfyna 6 | NPX70K0U4aof9xMg0I/M09WU+7l5or54uFWsrH+sx7/qDkSLwLfZ7WRNmQon/b+gglvoZkRZHYEa 7 | FaZg9kxK48pM6MMehX8n+QZFZ1QfPfoP2ajcsr14gXvEpqQa0SzjIn522nMqyXLKx38JQp7shil4 8 | 9S38w3EfAgMBAAEwDQYJKoZIhvcNAQEEBQADggEBAJrtSsuqdB3RvGZMriETpO0pqQsBhZ+JRYqs 9 | 5dFIiC+bdJE+dUB6v8fpv1exSQ0+i+e1oTs2I9Wd4eIQ4rlZCG9K6EYBKP9Z59OBDTf6luaisoul 10 | 6gnKW7+kUfQQkBfJJw/4RA7FbaAmYNGEEfXTwDMU+ZoqIO/PV+JsfOtFUdPcwv1hPQHTE+KR1DtR 11 | AC+A4Ak+fOoaRnyTprvbT4inaPdn6D9fBrIpO6hQSAtM5K9+/VaskMSFqw03DkADRyxHacdz9JLp 12 | 5ChDbRrXCDdT/a832acPDViS3nG/GhuSTK8mlrXeHjpG6vaSbKiXNXwrwz80k/XoNh3k5jlfrzUM 13 | CQ4= 14 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ValidateSignature", "XmlCryptoUtilities\ValidateSignature.csproj", "{CAA449E3-720D-4CD6-B03B-94991E11FF25}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x86 = Debug|x86 9 | Release|x86 = Release|x86 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {CAA449E3-720D-4CD6-B03B-94991E11FF25}.Debug|x86.ActiveCfg = Debug|x86 13 | {CAA449E3-720D-4CD6-B03B-94991E11FF25}.Debug|x86.Build.0 = Debug|x86 14 | {CAA449E3-720D-4CD6-B03B-94991E11FF25}.Release|x86.ActiveCfg = Release|x86 15 | {CAA449E3-720D-4CD6-B03B-94991E11FF25}.Release|x86.Build.0 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /test/static/feide_public.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMC 3 | Tk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UE 4 | CxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0B 5 | CQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoX 6 | DTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhl 7 | aW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBv 8 | cGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdA 9 | dW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlx 10 | AZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4Hln 11 | O4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZ 12 | jcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQ 13 | Yj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1j 14 | wKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3K 15 | jjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w== 16 | -----END CERTIFICATE----- 17 | -------------------------------------------------------------------------------- /test/static/signature_with_inclusivenamespaces.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICnTCCAgagAwIBAgIGAUBGHxqUMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYDVQQGEwJVUzETMBEG 3 | A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU 4 | MBIGA1UECwwLU1NPUHJvdmlkZXIxEjAQBgNVBAMMCWtsdWdsYWJzMjEcMBoGCSqGSIb3DQEJARYN 5 | aW5mb0Bva3RhLmNvbTAeFw0xMzA4MDMyMTM4MzhaFw00MzA4MDMyMTM5MzhaMIGRMQswCQYDVQQG 6 | EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UE 7 | CgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxEjAQBgNVBAMMCWtsdWdsYWJzMjEcMBoGCSqG 8 | SIb3DQEJARYNaW5mb0Bva3RhLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsCB9lJTH 9 | qB7vdM5jeOH84cW8u7IHYv4/OAPYF0fBYe9wJy19CgyM2OgiASuAcItnH4WhB+io2ZPwb/Xwl7Uu 10 | 4XmUE0l+mkCNuDYp5fXTZxwv5G6HvkAxXZio0Rk9T0VETCroxgpS5LxQ/o/owjR39S7xzRnj6ddX 11 | 3Mq2yGjKyBcCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAB1qGNqSNLLWq+RPcP+wOaWtYpJOJ8/MbZ 12 | EWWm9/KKHKXM6J/zgUUIXZi3czMeO+Y+X14PR8lGXoAHf5b/JavG9FmFvRn4fGa45VTVo2GfMN6K 13 | aIKF0obeCbYi/QUf8B+Xi1tSIJm1VCKRE7nnliQ/TzGaNulgWeyTbVkG0/X8LQ== 14 | -----END CERTIFICATE----- 15 | -------------------------------------------------------------------------------- /test/wsfed-metadata-tests.spec.ts: -------------------------------------------------------------------------------- 1 | import { SignedXml } from "../src/index"; 2 | import * as xpath from "xpath"; 3 | import * as xmldom from "@xmldom/xmldom"; 4 | import * as fs from "fs"; 5 | import { expect } from "chai"; 6 | import * as isDomNode from "@xmldom/is-dom-node"; 7 | 8 | describe("WS-Fed Metadata tests", function () { 9 | it("test validating WS-Fed Metadata", function () { 10 | const xml = fs.readFileSync("./test/static/wsfederation_metadata.xml", "utf-8"); 11 | const doc = new xmldom.DOMParser().parseFromString(xml); 12 | const signature = xpath.select1( 13 | "/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", 14 | doc, 15 | ); 16 | isDomNode.assertIsNodeLike(signature); 17 | const sig = new SignedXml(); 18 | sig.publicCert = fs.readFileSync("./test/static/wsfederation_metadata.pem"); 19 | sig.loadSignature(signature); 20 | const result = sig.checkSignature(xml); 21 | 22 | expect(result).to.be.true; 23 | expect(sig.getSignedReferences().length).to.equal(1); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": false, 4 | "node": true, 5 | "mocha": true, 6 | "es2020": true 7 | }, 8 | "root": true, 9 | "parser": "@typescript-eslint/parser", 10 | "plugins": ["@typescript-eslint", "deprecation"], 11 | "parserOptions": { 12 | "project": "./tsconfig.eslint.json", 13 | "ext": ".ts" 14 | }, 15 | "extends": [ 16 | "eslint:recommended", 17 | "plugin:@typescript-eslint/eslint-recommended", 18 | "plugin:@typescript-eslint/recommended", 19 | "prettier" 20 | ], 21 | "rules": { 22 | "no-console": "error", 23 | "no-prototype-builtins": "error", 24 | "one-var": ["error", "never"], 25 | "no-duplicate-imports": "error", 26 | "no-use-before-define": "error", 27 | "curly": "error", 28 | "eqeqeq": ["error", "smart"], 29 | "no-var": "error", 30 | "prefer-const": "error", 31 | "prefer-template": "error", 32 | "deprecation/deprecation": "error", 33 | "@typescript-eslint/no-non-null-assertion": "error", 34 | "@typescript-eslint/no-unused-vars": "error", 35 | "@typescript-eslint/no-this-alias": "error" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) Yaron Naveh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /test/static/wsfederation_metadata.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIC4jCCAcqgAwIBAgIQQNXrmzhLN4VGlUXDYCRT3zANBgkqhkiG9w0BAQsFADAt 3 | MSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4X 4 | DTE0MTAyODAwMDAwMFoXDTE2MTAyNzAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3Vu 5 | dHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQAD 6 | ggEPADCCAQoCggEBALyKs/uPhEf7zVizjfcr/ISGFe9+yUOqwpel38zgutvLHmFD 7 | 39E2hpPdQhcXn4c4dt1fU5KvkbcDdVbP8+e4TvNpJMy/nEB2V92zCQ/hhBjilwhF 8 | 1ETe1TMmVjALs0KFvbxW9ZN3EdUVvxFvz/gvG29nQhl4QWKj3x8opr89lmq14Z7T 9 | 0mzOV8kub+cgsOU/1bsKqrIqN1fMKKFhjKaetctdjYTfGzVQ0AJAzzbtg0/Q1wdY 10 | NAnhSDafygEv6kNiquk0r0RyasUUevEXs2LY3vSgKsKseI8ZZlQEMtE9/k/iAG7J 11 | NcEbVg53YTurNTrPnXJOU88mf3TToX14HpYsS1ECAwEAATANBgkqhkiG9w0BAQsF 12 | AAOCAQEAfolx45w0i8CdAUjjeAaYdhG9+NDHxop0UvNOqlGqYJexqPLuvX8iyUaY 13 | xNGzZxFgGI3GpKfmQP2JQWQ1E5JtY/n8iNLOKRMwqkuxSCKJxZJq4Sl/m/Yv7TS1 14 | P5LNgAj8QLCypxsWrTAmq2HSpkeSk4JBtsYxX6uhbGM/K1sEktKybVTHu22/7TmR 15 | qWTmOUy9wQvMjJb2IXdMGLG3hVntN/WWcs5w8vbt1i8Kk6o19W2MjZ95JaECKjBD 16 | YRlhG1KmSBtrsKsCBQoBzwH/rXfksTO9JoUYLXiW0IppB7DhNH4PJ5hZI91R8rR0 17 | H3/bKkLSuDaKLWSqMhozdhXsIIKvJQ== 18 | -----END CERTIFICATE----- 19 | -------------------------------------------------------------------------------- /src/hash-algorithms.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from "crypto"; 2 | import type { HashAlgorithm } from "./types"; 3 | 4 | export class Sha1 implements HashAlgorithm { 5 | getHash = function (xml) { 6 | const shasum = crypto.createHash("sha1"); 7 | shasum.update(xml, "utf8"); 8 | const res = shasum.digest("base64"); 9 | return res; 10 | }; 11 | 12 | getAlgorithmName = function () { 13 | return "http://www.w3.org/2000/09/xmldsig#sha1"; 14 | }; 15 | } 16 | 17 | export class Sha256 implements HashAlgorithm { 18 | getHash = function (xml) { 19 | const shasum = crypto.createHash("sha256"); 20 | shasum.update(xml, "utf8"); 21 | const res = shasum.digest("base64"); 22 | return res; 23 | }; 24 | 25 | getAlgorithmName = function () { 26 | return "http://www.w3.org/2001/04/xmlenc#sha256"; 27 | }; 28 | } 29 | 30 | export class Sha512 implements HashAlgorithm { 31 | getHash = function (xml) { 32 | const shasum = crypto.createHash("sha512"); 33 | shasum.update(xml, "utf8"); 34 | const res = shasum.digest("base64"); 35 | return res; 36 | }; 37 | 38 | getAlgorithmName = function () { 39 | return "http://www.w3.org/2001/04/xmlenc#sha512"; 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /test/static/integration/expectedVerify.xml: -------------------------------------------------------------------------------- 1 | b5GCZ2xpP5T7tbLWBTkOl4CYupQ=K4dI497ZCxzweDIrbndUSmtoezY=sH1gxKve8wlU8LlFVa2l6w3HMJ0=PI2xGt3XrVcxYZ34Kw7nFdq75c7Mmo7J0q7yeDhBprHuJal/KV9KyKG+Zy3bmQIxNwkPh0KMP5r1YMTKlyifwbWK0JitRCSa0Fa6z6+TgJi193yiR5S1MQ+esoQT0RzyIOBl9/GuJmXx/1rXnqrTxmL7UxtqKuM29/eHwF0QDUI= -------------------------------------------------------------------------------- /test/static/invalid_signature - hash.xml: -------------------------------------------------------------------------------- 1 | b5GCZ2xpP5T7tbLWBTkOl4CPupQ=K4dI497ZCxzweDIrbndUSmtoezY=sH1gxKve8wlU8LlFVa2l6w3HMJ0=PI2xGt3XrVcxYZ34Kw7nFdq75c7Mmo7J0q7yeDhBprHuJal/KV9KyKG+Zy3bmQIxNwkPh0KMP5r1YMTKlyifwbWK0JitRCSa0Fa6z6+TgJi193yiR5S1MQ+esoQT0RzyIOBl9/GuJmXx/1rXnqrTxmL7UxtqKuM29/eHwF0QDUI= -------------------------------------------------------------------------------- /test/static/invalid_signature - signature value.xml: -------------------------------------------------------------------------------- 1 | b5GCZ2xpP5T7tbLWBTkOl4CYupQ=K4dI497ZCxzweDIrbndUSmtoezY=sH1gxKve8wlU8LlFVa2l6w3HMJ0=PI2xGt3XrVcxYZ34Kw7nFdq75c7Mmo7J0q7yeDhBprHuJal/KV9KyKG+Zy3bmQIxNwkPh0KMP5r1YMTKlyifwbWK0JitRCSa0Fa6z6+TgJi193yiR5S1MQ+esoQT0RzyIOBl9/GuJmXx/1rXnqrTxmL7UxtqKuM29/eHwF0Q1UI= -------------------------------------------------------------------------------- /test/static/invalid_signature - non existing reference.xml: -------------------------------------------------------------------------------- 1 | b5GCZ2xpP5T7tbLWBTkOl4CYupQ=K4dI497ZCxzweDIrbndUSmtoezY=sH1gxKve8wlU8LlFVa2l6w3HMJ0=PI2xGt3XrVcxYZ34Kw7nFdq75c7Mmo7J0q7yeDhBprHuJal/KV9KyKG+Zy3bmQIxNwkPh0KMP5r1YMTKlyifwbWK0JitRCSa0Fa6z6+TgJi193yiR5S1MQ+esoQT0RzyIOBl9/GuJmXx/1rXnqrTxmL7UxtqKuM29/eHwF0QDUI= -------------------------------------------------------------------------------- /test/static/valid_signature.xml: -------------------------------------------------------------------------------- 1 | b5GCZ2xpP5T7tbLWBTkOl4CYupQ=K4dI497ZCxzweDIrbndUSmtoezY=sH1gxKve8wlU8LlFVa2l6w3HMJ0=PI2xGt3XrVcxYZ34Kw7nFdq75c7Mmo7J0q7yeDhBprHuJal/KV9KyKG+Zy3bmQIxNwkPh0KMP5r1YMTKlyifwbWK0JitRCSa0Fa6z6+TgJi193yiR5S1MQ+esoQT0RzyIOBl9/GuJmXx/1rXnqrTxmL7UxtqKuM29/eHwF0QDUI=1234 -------------------------------------------------------------------------------- /test/static/valid_signature_with_whitespace_in_digestvalue.xml: -------------------------------------------------------------------------------- 1 | b5GCZ2xpP5T7tbLWBTkOl4CYupQ= 2 | K4dI497ZCxzweDIrbndUSmtoezY= 3 | sH1gxKve8wlU8LlFVa2l6w3HMJ0= 4 | gGp+jskU2HohMdhaeGTdJBbN/rngzWrQs0+N4bqJDzHQEqUm6rVk0mDoFybJaW0AEXf/dSVhM0faYTwQK0p9aipsAORTaPq677GcdKwyEHHRnly064D8GlikyQ49451SEViy89kYZO1yf+x5MNHNyCi7VVRIixbsSLOUgu0A9Yo= 5 | -------------------------------------------------------------------------------- /test/static/invalid_signature - changed content.xml: -------------------------------------------------------------------------------- 1 | b5GCZ2xpP5T7tbLWBTkOl4CYupQ=K4dI497ZCxzweDIrbndUSmtoezY=sH1gxKve8wlU8LlFVa2l6w3HMJ0=PI2xGt3XrVcxYZ34Kw7nFdq75c7Mmo7J0q7yeDhBprHuJal/KV9KyKG+Zy3bmQIxNwkPh0KMP5r1YMTKlyifwbWK0JitRCSa0Fa6z6+TgJi193yiR5S1MQ+esoQT0RzyIOBl9/GuJmXx/1rXnqrTxmL7UxtqKuM29/eHwF0QDUI=1234 -------------------------------------------------------------------------------- /test/static/valid_signature_with_lowercase_id_attribute.xml: -------------------------------------------------------------------------------- 1 | AAGWFnPFdPl0aU4854Deo+j9BmU=79MH3RaPsyFcSyrzl4Jrpwp/lgo=MEdYYk8XXRBbW5Hlo8GlIO9J0fc=aFMgQTWuz+T0AzqERRTq/+XAxZmIs+ff031I579zfDTD/PjrCOhb4TVAkgydZajUkZwbOc5/mnBs9S/nqfABh1JXvqO/a+U+AzgSDoZesJ3OMHcPPSFt+5iYASjsV0B3MLUds4iNl76ETcwp1HC6u8rRspQ3uWzFt2zBzfEvmtY=1234 -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Test Status 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | jobs: 10 | test: 11 | name: Test Code 12 | env: 13 | CI: true 14 | 15 | strategy: 16 | matrix: 17 | os: [ubuntu-latest] 18 | node-version: [16, 18, 20] 19 | experimental: [false] 20 | include: 21 | - os: ubuntu-latest 22 | node-version: latest 23 | experimental: true 24 | runs-on: ${{ matrix.os }} 25 | continue-on-error: ${{ matrix.experimental }} 26 | 27 | steps: 28 | - uses: actions/checkout@v4 29 | - name: Use Node.js ${{ matrix.node-version }} on ${{ matrix.os }} 30 | uses: actions/setup-node@v4 31 | with: 32 | node-version: ${{ matrix.node-version }} 33 | - run: npm ci 34 | - run: npm test 35 | - run: npm update 36 | - run: npm ci 37 | - run: npm test 38 | - name: Codecov 39 | uses: codecov/codecov-action@v3.1.4 40 | with: 41 | verbose: true 42 | 43 | lint: 44 | name: Lint Code 45 | env: 46 | CI: true 47 | runs-on: ubuntu-latest 48 | steps: 49 | - uses: actions/checkout@v4 50 | - uses: actions/setup-node@v4 51 | with: 52 | node-version: "lts/*" 53 | - run: | 54 | npm ci 55 | npm run lint 56 | -------------------------------------------------------------------------------- /test/static/keyinfo.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDtTCCAp2gAwIBAgIJAKg4VeVcIDz1MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV 3 | BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX 4 | aWRnaXRzIFB0eSBMdGQwHhcNMTUwODEzMDE1NDIwWhcNMTUwOTEyMDE1NDIwWjBF 5 | MQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 6 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 7 | CgKCAQEAxG3ouM7U+fXbJt69X1H6d4UNg/uRr06pFuU9RkfIwNC+yaXyptqB3ynX 8 | KsL7BFt4DCd0fflRvJAx3feJIDp16wN9GDVHcufWMYPhh2j5HcTW/j9JoIJzGhJy 9 | vO00YKBt+hHy83iN1SdChKv5y0iSyiPP5GnqFw+ayyHoM6hSO0PqBou1Xb0ZSIE+ 10 | DHosBnvVna5w2AiPY4xrJl9yZHZ4Q7DfMiYTgstjETio4bX+6oLiBnYktn7DjdEs 11 | lqhffVme4PuBxNojI+uCeg/sn4QVLd/iogMJfDWNuLD8326Mi/FE9cCRvFlvAiMS 12 | aebMI3zPaySsxTK7Zgj5TpEbmbHI9wIDAQABo4GnMIGkMB0GA1UdDgQWBBSVGgvo 13 | W4MhMuzBGce29PY8vSzHFzB1BgNVHSMEbjBsgBSVGgvoW4MhMuzBGce29PY8vSzH 14 | F6FJpEcwRTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV 15 | BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAKg4VeVcIDz1MAwGA1UdEwQF 16 | MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAJu1rqs+anD74dbdwgd3CnqnQsQDJiEX 17 | mBhG2leaGt3ve9b/9gKaJg2pyb2NyppDe1uLqh6nNXDuzg1oNZrPz5pJL/eCXPl7 18 | FhxhMUi04TtLf8LeNTCIWYZiFuO4pmhohHcv8kRvYR1+6SkLTC8j/TZerm7qvesS 19 | iTQFNapa1eNdVQ8nFwVkEtWl+JzKEM1BlRcn42sjJkijeFp7DpI7pU+PnYeiaXpR 20 | v5pJo8ogM1iFxN+SnfEs0EuQ7fhKIG9aHKi7bKZ7L6SyX7MDIGLeulEU6lf5D9Bf 21 | XNmcMambiS0pXhL2QXajt96UBq8FT2KNXY8XNtR4y6MyyCzhaiZZcc8= 22 | -----END CERTIFICATE----- 23 | -------------------------------------------------------------------------------- /test/static/windows_store_certificate.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDyTCCArGgAwIBAgIQNP+YKvSo8IVArhlhpgc/xjANBgkqhkiG9w0BAQsFADCB 3 | jjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1Jl 4 | ZG1vbmQxHjAcBgNVBAoMFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEWMBQGA1UECwwN 5 | V2luZG93cyBTdG9yZTEgMB4GA1UEAwwXV2luZG93cyBTdG9yZSBMaWNlbnNpbmcw 6 | HhcNMTExMTE3MjMwNTAyWhcNMzYxMTEwMjMxMzQ0WjCBjjELMAkGA1UEBhMCVVMx 7 | EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1JlZG1vbmQxHjAcBgNVBAoM 8 | FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEWMBQGA1UECwwNV2luZG93cyBTdG9yZTEg 9 | MB4GA1UEAwwXV2luZG93cyBTdG9yZSBMaWNlbnNpbmcwggEiMA0GCSqGSIb3DQEB 10 | AQUAA4IBDwAwggEKAoIBAQCcr4/vgqZFtzMqy3jO0XHjBUNx6j7ZTXEnNpLl2VSe 11 | zVQA9KK2RlvroXKhYMUUdJpw+txm1mqi/W7D9QOYTq1e83GLhWC9IRh/OSmSYt0e 12 | kgVLB+icyRH3dtpYcJ5sspU2huPf4I/Nc06OuXlMsD9MU4Ug9IBD2HSDBEquhGRo 13 | xV64YuEH4645oB14LlEay0+JZlkKZ/mVhx/sdzSBfrda1X/Ckc7SOgnTSM3d/DnO 14 | 5DKwV2WYn+7i/rBqe4/op6IqQMrPpHyem9Sny+i0xiUMA+1IwkX0hs0gvHM6zDww 15 | TMDiTapbCy9LnmMx65oMq56hhsQydLEmquq8lVYUDEzLAgMBAAGjITAfMB0GA1Ud 16 | DgQWBBREzrOBz7zw+HWskxonOXAPMa6+NzANBgkqhkiG9w0BAQsFAAOCAQEAeVtN 17 | 4c6muxO6yfht9SaxEfleUBIjGfe0ewLBp00Ix7b7ldJ/lUQcA6y+Drrl7vjmkHQK 18 | OU3uZiFbCxTvgTcoz9o+1rzR/WPXmqH5bqu6ua/UrobGKavAScqqI/G6o56Xmx/y 19 | oErWN0VapN370crKJvNWxh3yw8DCl+W0EcVRiWX5lFsMBNBbVpK4Whp+VhkSJilu 20 | iRpe1B35Q8EqOz/4RQkOpVI0dREnuSYkBy/h2ggCtiQ5yfvH5zCdcfhFednYDevS 21 | axmt3W5WuHz8zglkg+OQ3qpXaXySRlrmLdxEmWu2MOiZbQkU2ZjBSQmvFAOy0dd6 22 | P1YLS4+Eyh5drQJc0Q== 23 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /test/static/valid_signature_with_root_level_sig_namespace.xml: -------------------------------------------------------------------------------- 1 | b5GCZ2xpP5T7tbLWBTkOl4CYupQ=K4dI497ZCxzweDIrbndUSmtoezY=sH1gxKve8wlU8LlFVa2l6w3HMJ0=rR8+4xHiI8GQJ9Wty2TUbNI7Dd4uc89/BsAygYfeobEjmt4awzg6bQNA0nuQ+VggiPCYdKuKL8cPI7FUhk8osbVKdLPdy+rdJnibsyNpV87R7W5GZlFBEu/NqG6EYOMTHjpD4hq+H8ZeHC5YZDHPknPzJV8+A1UKN/BL2oWMQcg=1234 2 | -------------------------------------------------------------------------------- /example/example.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | 3 | const select = require("xml-crypto").xpath; 4 | const dom = require("@xmldom/xmldom").DOMParser; 5 | const SignedXml = require("xml-crypto").SignedXml; 6 | const fs = require("fs"); 7 | 8 | function signXml(xml, xpath, key, dest) { 9 | const sig = new SignedXml(); 10 | sig.privateKey = fs.readFileSync(key); 11 | sig.addReference(xpath); 12 | sig.computeSignature(xml); 13 | fs.writeFileSync(dest, sig.getSignedXml()); 14 | } 15 | 16 | function validateXml(xml, key) { 17 | const doc = new dom().parseFromString(xml); 18 | const signature = select( 19 | "/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", 20 | doc, 21 | )[0]; 22 | const sig = new SignedXml(); 23 | sig.publicCert = key; 24 | sig.loadSignature(signature.toString()); 25 | const res = sig.checkSignature(xml); 26 | if (!res) { 27 | console.log(sig.validationErrors); 28 | } 29 | return res; 30 | } 31 | 32 | const xml = "" + "" + "Harry Potter" + "" + ""; 33 | 34 | //sign an xml document 35 | signXml(xml, "//*[local-name(.)='book']", "client.pem", "result.xml"); 36 | 37 | console.log("xml signed successfully"); 38 | 39 | const signedXml = fs.readFileSync("result.xml").toString(); 40 | console.log("validating signature..."); 41 | 42 | //validate an xml document 43 | if (validateXml(signedXml, "client_public.pem")) { 44 | console.log("signature is valid"); 45 | } else { 46 | console.log("signature not valid"); 47 | } 48 | -------------------------------------------------------------------------------- /test/static/valid_signature wsu.xml: -------------------------------------------------------------------------------- 1 | 5jkdJLKVpfEiAQ0k5bnvfCQJKks=97gNxHth/Gc2wH4FiTiWJJrLaHI=TUkwwDGRfgW3CORC9RvimMKtFpU=V5wZiNWAzyQmAhm+F3ji0IIq9ariZ/ORCdHXjhwDU36yPUuRiyLoy7WJvl7tkyV/C/D7R2WiQ/TwbM3973ZWToKUwAM/FSzOTu+4P/ea8zZ6SDxYTFxDwvxSdtfiYqZ/C61EApnNU5haoyiZ6H9ZBeJaERWIDI+fpJcCA5c6sb0= -------------------------------------------------------------------------------- /test/static/invalid_signature - wsu - hash.xml: -------------------------------------------------------------------------------- 1 | kapR1Bn68VZxlpAEcUqcpOiL1LQ=Ih44YjG8IC7apTJSIkMLSjiU0H0=3jbv3y5YtUUG6EIQSVL5faQorFY=tk7uiJCzpfI9TUGAuZuLELPqN7LdVIhljaJRKHdaBpbgu3XH5YiGQXbOOmGbX6ghr2mabbMgw2kXQJbUATzqdQn+wRbeMRqFaj4vBpEoTohiwdoIw67zGbSCXKoGSZ7FxJADe53gS955wZgdcGt+Ni7ec5EbXb0XtzM6gDF+eUo= -------------------------------------------------------------------------------- /test/static/valid_signature_with_reference_keyInfo.xml: -------------------------------------------------------------------------------- 1 | b5GCZ2xpP5T7tbLWBTkOl4CYupQ=K4dI497ZCxzweDIrbndUSmtoezY=sH1gxKve8wlU8LlFVa2l6w3HMJ0=PI2xGt3XrVcxYZ34Kw7nFdq75c7Mmo7J0q7yeDhBprHuJal/KV9KyKG+Zy3bmQIxNwkPh0KMP5r1YMTKlyifwbWK0JitRCSa0Fa6z6+TgJi193yiR5S1MQ+esoQT0RzyIOBl9/GuJmXx/1rXnqrTxmL7UxtqKuM29/eHwF0QDUI= -------------------------------------------------------------------------------- /test/static/invalid_signature - wsu - changed content.xml: -------------------------------------------------------------------------------- 1 | 5jkdJLKVpfEiAQ0k5bnvfCQJKks=97gNxHth/Gc2wH4FiTiWJJrLaHI=mXRUtj7KJU3kMPLD9R30CGEiWio=CRK8LTGiMM5p++3usB6Nxjg5WrPfvq97bFzHwtt9Sijqf1BqqCHLnQLxzhtPR7j6g0TJaQt4bmF8neO7IwgloSWX/ZXUl9dz5Ax9IMfESBI0L8Ew2BE1osZp3Nlc0xSSIVFKMfo9gvqi317jBjr/VklqjHXjMfhtGv8GATpdwPQ= -------------------------------------------------------------------------------- /test/static/invalid_signature - wsu - invalid signature value.xml: -------------------------------------------------------------------------------- 1 | 5jkdJLKVpfEiAQ0k5bnvfCQJKks=97gNxHth/Gc2wH4FiTiWJJrLaHI=mXRUtj7KJU3kMPLD9R30CGEiWio=CRK8LTGiMM5p++3usB6Nxjg5WrPfvq97bFzHwtt9Sijqf1BqqCHLnQLxzhtPR7j6g0TJaQt4bmF8neO7IwgloSWX/ZXUl9dz5Ax9IMfESBI0L8Ew2BE1osZp3Nlc0xSSIVFKMfo9gvqi317jBkr/VklqjHXjMfhtGv8GATpdwPQ= -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("XmlCryptoUtilities")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("XmlCryptoUtilities")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2012")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8305ddd7-a079-45b3-8db1-83728172475e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /test/static/invalid_signature - wsu - non existing reference.xml: -------------------------------------------------------------------------------- 1 | kapR1Bn6OVZxlpAEcUqcpOiL1LQ=Ih44YjG8IC7apTJSIkMLSjiU0H0=3jbv3y5YtUUG6EIQSVL5faQorFY=tk7uiJCzpfI9TUGAuZuLELPqN7LdVIhljaJRKHdaBpbgu3XH5YiGQXbOOmGbX6ghr2mabbMgw2kXQJbUATzqdQn+wRbeMRqFaj4vBpEoTohiwdoIw67zGbSCXKoGSZ7FxJADe53gS955wZgdcGt+Ni7ec5EbXb0XtzM6gDF+eUo= -------------------------------------------------------------------------------- /test/static/windows_store_signature.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | cdiU06eD8X/w1aGCHeaGCG9w/kWZ8I099rw4mmPpvdU= 14 | 15 | 16 | SjRIxS/2r2P6ZdgaR9bwUSa6ZItYYFpKLJZrnAa3zkMylbiWjh9oZGGng2p6/gtBHC2dSTZlLbqnysJjl7mQp/A3wKaIkzjyRXv3kxoVaSV0pkqiPt04cIfFTP0JZkE5QD/vYxiWjeyGp1dThEM2RV811sRWvmEs/hHhVxb32e8xCLtpALYx3a9lW51zRJJN0eNdPAvNoiCJlnogAoTToUQLHs72I1dECnSbeNPXiG7klpy5boKKMCZfnVXXkneWvVFtAA1h2sB7ll40LEHO4oYN6VzD+uKd76QOgGmsu9iGVyRvvmMtahvtL1/pxoxsTRedhKq6zrzCfT8qfh3C1w== 17 | 18 | -------------------------------------------------------------------------------- /.grenrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | dataSource: "prs", 3 | prefix: "", 4 | onlyMilestones: false, 5 | ignoreTagsWith: [], 6 | ignoreLabels: [], 7 | tags: "all", 8 | groupBy: { 9 | "Major Changes": ["semver-major", "breaking-change"], 10 | "Minor Changes": ["semver-minor", "enhancement", "new-feature"], 11 | Dependencies: ["dependencies"], 12 | "Bug Fixes": ["semver-patch", "bug", "security"], 13 | Documentation: ["documentation"], 14 | "Technical Tasks": ["chore"], 15 | Other: ["..."], 16 | }, 17 | changelogFilename: "CHANGELOG.md", 18 | username: "node-saml", 19 | repo: "xml-crypto", 20 | template: { 21 | issue: function (placeholders) { 22 | const parts = [ 23 | "-", 24 | placeholders.labels, 25 | placeholders.name, 26 | `[${placeholders.text}](${placeholders.url})`, 27 | ]; 28 | return parts 29 | .filter((_) => _) 30 | .join(" ") 31 | .replace(" ", " "); 32 | }, 33 | release: function (placeholders) { 34 | placeholders.body = placeholders.body.replace( 35 | "*No changelog for this release.*", 36 | "\n_No changelog for this release._", 37 | ); 38 | return `## ${placeholders.release} (${placeholders.date})\n${placeholders.body}`; 39 | }, 40 | group: function (placeholders) { 41 | const iconMap = { 42 | Enhancements: "🚀", 43 | "Minor Changes": "🚀", 44 | "Bug Fixes": "🐛", 45 | Documentation: "📚", 46 | "Technical Tasks": "⚙️", 47 | "Major Changes": "💣", 48 | Dependencies: "🔗", 49 | }; 50 | const icon = iconMap[placeholders.heading] || "🙈"; 51 | return "\n### " + icon + " " + placeholders.heading + "\n"; 52 | }, 53 | }, 54 | }; 55 | -------------------------------------------------------------------------------- /test/static/idp_certificate.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIFFzCCAv+gAwIBAgIUaAU88KUbZLe7NwTw+jdCHIDU6wIwDQYJKoZIhvcNAQEL 3 | BQAwGjEYMBYGA1UEAwwPaWRwLmV4YW1wbGUuY29tMCAXDTI1MDkwODExMTUzMFoY 4 | DzIxMjUwODE1MTExNTMwWjAaMRgwFgYDVQQDDA9pZHAuZXhhbXBsZS5jb20wggIi 5 | MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXpgSoph176VQPw+4e91UAL6j0 6 | TbL/aI3Amj62TU91KOk4xigy+8xFSeU2IC64W7abfFq+25K+1ybJmMBq94UKyKab 7 | 7yeXmen2xJ9PT5br4TwnsbeBZrziXSR8uTE60DdWLZYJEBREgu96JeEWLzP/0Hfn 8 | FlnuG5kXlb6rpy7l723YeDvU9lvsm6Rj46m5R8j4CSenKmLsHSIhmNP59SsEpJ16 9 | D+RfKcrKqxPxp6t/oCEKXjpmOeGoX9WT5V9UMxrGFgY2YLab9tLCIK48i6rgXpHU 10 | nbMq2XyAT58bSG/Tif99hoiQ2ovzsVUrVeCa4/uUg/pr+w1bZnIBl6R8WVPTVwgm 11 | YN+8Ww27aLiNksCn70t74XZLr9xnYnbnj324AiZp9Z48vDECm41Tc+V9eqGNO/5Y 12 | LgZqoGTy4El3AMcNF3lkecZ2UZKMI341pI1vHyRG0jCr2ZYpy30pYQKd+Z7AvZKM 13 | UTJFQfBIOn3zXN6SA8lWZLPOW4VTdOfcGjQij3AUDeTeilUigpRgkTl97WUrGfas 14 | vLXMrdRoXYxjGPe+s4+tf+gnKhTVQ6h6we+ISaFVOeXpCrOUwZM0OdikQtKYgH0G 15 | 9OrJKxDZDl4YkkYFqqhyw5Eum9HZwMU8631lkBSqMRgz8AX7KdBn1PrGS6wOp+GC 16 | 28L1ISeRxRriWtaeXQIDAQABo1MwUTAdBgNVHQ4EFgQULRbUCREu3zQABqNW8LMO 17 | fraF5BMwHwYDVR0jBBgwFoAULRbUCREu3zQABqNW8LMOfraF5BMwDwYDVR0TAQH/ 18 | BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAA6Jm3pll7XHBY/oXrtRAu60RpH4p 19 | cZBSf68zhCQKUnXALy2FWrUGU8uVCJJuxXIcxszTOCZmwVF12YceIFpBrWHxKCDZ 20 | WYDO6hrwZvsa2vh5mXDZo3c/HX6GmJR4f4oIIZnbxFhXR30419PlrwMW3Rk7rnVS 21 | Dz/HpQfdS4y8jYgsm2dIRo+PXQytFRCDj4afsT3eZa27QjFxLTuK+SwkhupSH1WW 22 | YmqL9+iIJiLL/ntfM4MwtOUwcfqI0ttbvFZZIPneBCuEDLn/zJ/QBV3ZvjQDt53W 23 | 21HaPGPHBBfVZVroZPvuGvulWRLeECI1Hmbl3al/2aOC0LWzPIk8dlTcN+EWcCEu 24 | fpTOEgkob8waEyxlX0Z5OBjkCHpyDTPGkxBBOCJv88Frx7qdbu8eSV0OviuaM/B7 25 | ky2NbDMKIybX4tf/Q8FNfjPLvTv+8nbrMz6kTno3RR2YC7ttI7Glb/eOg3F/ouF4 26 | wcoPAj+OyU5Q5WJMMaZ9cXF9pwszsglLbFms+WD5PFxlloh6I1hO7TccWKTeUJ5f 27 | YZSYYm31JqWit3DBltXTyRyL7KFSdT/FyRBk62YLCJqJmcukIUJUTya73/RmjW1M 28 | 4zMBNaIj/pH77opKWnVbm9F4XnBCG4r9+FRXdV2zKW6DgvDzQ6DaZ+0cwC36vSqk 29 | DyjZYv/tviuWfM8= 30 | -----END CERTIFICATE----- 31 | -------------------------------------------------------------------------------- /test/key-info-tests.spec.ts: -------------------------------------------------------------------------------- 1 | import * as xmldom from "@xmldom/xmldom"; 2 | import * as fs from "fs"; 3 | import * as xpath from "xpath"; 4 | import { SignedXml } from "../src/index"; 5 | import { expect } from "chai"; 6 | import * as isDomNode from "@xmldom/is-dom-node"; 7 | 8 | describe("KeyInfo tests", function () { 9 | it("adds X509Certificate element during signature", function () { 10 | const xml = ""; 11 | const sig = new SignedXml(); 12 | sig.privateKey = fs.readFileSync("./test/static/client.pem"); 13 | sig.publicCert = fs.readFileSync("./test/static/client_public.pem"); 14 | sig.canonicalizationAlgorithm = "http://www.w3.org/2001/10/xml-exc-c14n#"; 15 | sig.signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; 16 | sig.computeSignature(xml); 17 | const signedXml = sig.getSignedXml(); 18 | const doc = new xmldom.DOMParser().parseFromString(signedXml); 19 | const x509 = xpath.select("//*[local-name(.)='X509Certificate']", doc.documentElement); 20 | isDomNode.assertIsArrayOfNodes(x509); 21 | 22 | expect(x509.length, "X509Certificate element should exist").to.equal(1); 23 | }); 24 | 25 | it("make sure private hmac key is not leaked due to key confusion", function () { 26 | const xml = "" + "" + "Harry Potter" + "" + ""; 27 | const sig = new SignedXml(); 28 | sig.privateKey = fs.readFileSync("./test/static/hmac.key"); 29 | sig.publicCert = fs.readFileSync("./test/static/hmac.key"); 30 | sig.signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#hmac-sha1"; 31 | sig.enableHMAC(); 32 | sig.addReference({ 33 | xpath: "//*[local-name(.)='book']", 34 | digestAlgorithm: "http://www.w3.org/2000/09/xmldsig#sha1", 35 | transforms: ["http://www.w3.org/2001/10/xml-exc-c14n#"], 36 | }); 37 | sig.canonicalizationAlgorithm = "http://www.w3.org/2001/10/xml-exc-c14n#"; 38 | sig.computeSignature(xml); 39 | 40 | const doc = new xmldom.DOMParser().parseFromString(sig.getSignedXml()); 41 | const keyInfo = xpath.select1("//*[local-name(.)='KeyInfo']", doc); 42 | 43 | expect(keyInfo).to.be.undefined; 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /test/static/unsigned_saml_response.xml: -------------------------------------------------------------------------------- 1 | 9 | https://idp.example.com/ 10 | 11 | 12 | 13 | 18 | https://idp.example.com/ 19 | 20 | nameId 23 | 24 | 28 | 29 | 30 | 33 | 34 | audience 35 | 36 | 37 | 41 | 42 | urn:oasis:names:tc:SAML:2.0:ac:classes:Password 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/enveloped-signature.ts: -------------------------------------------------------------------------------- 1 | import * as xpath from "xpath"; 2 | import * as isDomNode from "@xmldom/is-dom-node"; 3 | 4 | import type { 5 | CanonicalizationOrTransformationAlgorithm, 6 | CanonicalizationOrTransformationAlgorithmProcessOptions, 7 | CanonicalizationOrTransformAlgorithmType, 8 | } from "./types"; 9 | 10 | export class EnvelopedSignature implements CanonicalizationOrTransformationAlgorithm { 11 | protected includeComments = false; 12 | 13 | constructor() { 14 | this.includeComments = false; 15 | } 16 | 17 | process(node: Node, options: CanonicalizationOrTransformationAlgorithmProcessOptions): Node { 18 | if (null == options.signatureNode) { 19 | const signature = xpath.select1( 20 | "./*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", 21 | node, 22 | ); 23 | if (isDomNode.isNodeLike(signature) && signature.parentNode) { 24 | signature.parentNode.removeChild(signature); 25 | } 26 | return node; 27 | } 28 | const signatureNode = options.signatureNode; 29 | const expectedSignatureValue = xpath.select1( 30 | ".//*[local-name(.)='SignatureValue']/text()", 31 | signatureNode, 32 | ); 33 | if (isDomNode.isTextNode(expectedSignatureValue)) { 34 | const expectedSignatureValueData = expectedSignatureValue.data; 35 | 36 | const signatures = xpath.select( 37 | ".//*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", 38 | node, 39 | ); 40 | for (const nodeSignature of Array.isArray(signatures) ? signatures : []) { 41 | const signatureValue = xpath.select1( 42 | ".//*[local-name(.)='SignatureValue']/text()", 43 | nodeSignature, 44 | ); 45 | if (isDomNode.isTextNode(signatureValue)) { 46 | const signatureValueData = signatureValue.data; 47 | if (expectedSignatureValueData === signatureValueData) { 48 | if (nodeSignature.parentNode) { 49 | nodeSignature.parentNode.removeChild(nodeSignature); 50 | } 51 | } 52 | } 53 | } 54 | } 55 | return node; 56 | } 57 | 58 | getAlgorithmName(): CanonicalizationOrTransformAlgorithmType { 59 | return "http://www.w3.org/2000/09/xmldsig#enveloped-signature"; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "xml-crypto", 3 | "version": "6.0.0", 4 | "private": false, 5 | "description": "Xml digital signature and encryption library for Node.js", 6 | "keywords": [ 7 | "xml", 8 | "digital signature", 9 | "xml encryption", 10 | "x.509 certificate" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/node-saml/xml-crypto.git" 15 | }, 16 | "license": "MIT", 17 | "author": "Yaron Naveh (http://webservices20.blogspot.com/)", 18 | "contributors": [ 19 | "LoneRifle ", 20 | "Chris Barth " 21 | ], 22 | "main": "./lib", 23 | "files": [ 24 | "lib", 25 | "LICENSE", 26 | "README.md" 27 | ], 28 | "scripts": { 29 | "build": "npx tsc", 30 | "changelog": "gren changelog --override --generate", 31 | "lint": "eslint \"{src,test}/*.ts\" --cache && npm run prettier-check", 32 | "lint:fix": "eslint --fix \"{src,test}/*.ts\" && npm run prettier-format", 33 | "prepare": "tsc", 34 | "prettier-check": "prettier --config .prettierrc.json --check .", 35 | "prettier-format": "prettier --config .prettierrc.json --write .", 36 | "prerelease": "git clean -xfd && npm ci && npm test", 37 | "release": "release-it", 38 | "test": "nyc mocha" 39 | }, 40 | "dependencies": { 41 | "@xmldom/is-dom-node": "^1.0.1", 42 | "@xmldom/xmldom": "^0.8.10", 43 | "xpath": "^0.0.33" 44 | }, 45 | "devDependencies": { 46 | "@cjbarth/github-release-notes": "^4.2.0", 47 | "@istanbuljs/nyc-config-typescript": "^1.0.2", 48 | "@prettier/plugin-xml": "^3.2.2", 49 | "@types/chai": "^4.3.11", 50 | "@types/mocha": "^10.0.6", 51 | "@types/node": "^16.18.69", 52 | "@typescript-eslint/eslint-plugin": "^6.18.1", 53 | "@typescript-eslint/parser": "^6.18.1", 54 | "chai": "^4.3.10", 55 | "choma": "^1.2.1", 56 | "ejs": "^3.1.9", 57 | "eslint": "^8.56.0", 58 | "eslint-config-prettier": "^9.0.0", 59 | "eslint-plugin-deprecation": "^2.0.0", 60 | "lcov": "^1.16.0", 61 | "mocha": "^10.2.0", 62 | "nyc": "^15.1.0", 63 | "prettier": "^3.1.0", 64 | "prettier-plugin-packagejson": "^2.4.6", 65 | "release-it": "^16.3.0", 66 | "source-map-support": "^0.5.21", 67 | "ts-node": "^10.9.1", 68 | "typescript": "^5.3.2" 69 | }, 70 | "engines": { 71 | "node": ">=16" 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /test/static/id_with_quotes.xml: -------------------------------------------------------------------------------- 1 | https://openidp.feide.no 2 | https://openidp.feide.no 3 | 4 | 5 | RnNjoyUguwze5w2R+cboyTHlkQk=aw5711jKP7xragunjRRCAD4mT4xKHc37iohBpQDbdSomD3ksOSB96UZQp0MtaC3xlVSkMtYw85Om96T2q2xrxLLYVA50eFJEMMF7SCVPStWTVjBlaCuOPEQxIaHyJs9Sy3MCEfbBh4Pqn9IJBd1kzwdlCrWWjAmksbFFg5wHQJA= 6 | MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w== 7 | some text 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/ValidateSignature.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {CAA449E3-720D-4CD6-B03B-94991E11FF25} 9 | Exe 10 | Properties 11 | XmlCryptoUtilities 12 | XmlCryptoUtilities 13 | v4.0 14 | Client 15 | 512 16 | 17 | 18 | x86 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | x86 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 59 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [master] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [master] 20 | schedule: 21 | - cron: "21 12 * * 1" 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: ["javascript"] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 37 | # Learn more: 38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 39 | 40 | steps: 41 | - name: Checkout repository 42 | uses: actions/checkout@v4 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v3 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | - name: Autobuild 57 | uses: github/codeql-action/autobuild@v3 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | #- run: | 67 | # make bootstrap 68 | # make release 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v3 72 | -------------------------------------------------------------------------------- /test/validators/XmlCryptoJava/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | XML Crypto Java Tests 5 | org.nodejs 6 | xml-crypto-java 7 | 1.0.0-SNAPSHOT 8 | jar 9 | 2015 10 | 11 | 12 | MIT License 13 | http://www.opensource.org/licenses/mit-license.php 14 | 15 | 16 | 17 | 18 | fcorneli 19 | Frank Cornelis 20 | info@e-contract.be 21 | 22 | 23 | 24 | 25 | junit 26 | junit 27 | 4.13.1 28 | test 29 | 30 | 31 | org.slf4j 32 | slf4j-api 33 | 1.7.12 34 | test 35 | 36 | 37 | org.slf4j 38 | slf4j-log4j12 39 | 1.7.12 40 | test 41 | 42 | 43 | log4j 44 | log4j 45 | 1.2.17 46 | test 47 | 48 | 49 | commons-io 50 | commons-io 51 | 2.7 52 | test 53 | 54 | 55 | 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-compiler-plugin 60 | 3.3 61 | 62 | 1.7 63 | 1.7 64 | UTF-8 65 | 66 | 67 | 68 | 69 | 70 | UTF-8 71 | 72 | 73 | -------------------------------------------------------------------------------- /test/static/valid_signature_utf8.xml: -------------------------------------------------------------------------------- 1 | urn:issueris/s3v+lPE4xdF9ImlbRMoXJjOPWKH8C/ixcfRaDPgU=DgIb3UlS5p7j6iEUD1SsaPs2HqHnI3nC2ixw7CRebgcz8lG6o7AbgRsy57ePr1hX90lxOGvO8Txz8kJDq3vWH6g9fU0Nu+1QxCq4/mb3a2Jr84lFDivSUQa7YEugECH789EvRzEXRTseKx8XYKjlH6ffvai3Oqn9kSLWPQbY7xI=MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAWMRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEyMzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPdVu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9xO3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8jufz2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcNAQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5sT/txBnVJGziyO8DPYdu2fPMER8ajJflвКонтактеurn:myappсообщить@bar.comсообщить вКонтактеurn:oasis:names:tc:SAML:2.0:ac:classes:unspecified -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/utilities.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Security.Cryptography.Xml; 6 | using System.Security.Cryptography; 7 | using System.Security.Cryptography.X509Certificates; 8 | using System.Xml; 9 | using System.IO; 10 | 11 | namespace ConsoleApplication31 12 | { 13 | /* 14 | class Program 15 | { 16 | static void Main(string[] args) 17 | { 18 | GetCanonization(); 19 | //GetSignature(); 20 | 21 | } 22 | 23 | static void GetSignature() 24 | { 25 | XmlDocument doc = new XmlDocument(); 26 | //doc.LoadXml(""); 27 | doc.LoadXml(""); 28 | SignedXml signedXml = new SignedXml(doc); 29 | 30 | var c = new X509Certificate2( 31 | File.ReadAllBytes(@"C:\Program Files\Microsoft WSE\v2.0\Samples\Sample Test Certificates\Client Private.pfx"), "wse2qs"); 32 | 33 | signedXml.SigningKey = c.PrivateKey; 34 | signedXml.Signature.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#"; 35 | 36 | Reference ref0 = new Reference(); 37 | ref0.Uri = "#_0"; 38 | Reference ref1 = new Reference(); 39 | ref1.Uri = "#_1"; 40 | Reference ref2 = new Reference(); 41 | ref2.Uri = "#_2"; 42 | 43 | var t = new XmlDsigExcC14NTransform(); 44 | ref0.AddTransform(t); 45 | ref1.AddTransform(t); 46 | ref2.AddTransform(t); 47 | 48 | signedXml.AddReference(ref0); 49 | signedXml.AddReference(ref1); 50 | signedXml.AddReference(ref2); 51 | 52 | signedXml.ComputeSignature(); 53 | var xmlDigitalSignature = signedXml.GetXml(); 54 | var s = xmlDigitalSignature.OuterXml; 55 | } 56 | 57 | static void GetCanonization() 58 | { 59 | var c = new XmlDsigExcC14NTransform(true, ""); 60 | var doc = new XmlDocument(); 61 | doc.PreserveWhitespace = true; 62 | doc.LoadXml(""); 63 | var node = doc.SelectSingleNode("//*[local-name(.)='x']"); 64 | var nodes = node.SelectNodes(".|.//*|.//text()|.//@*"); 65 | c.LoadInput(nodes); 66 | 67 | var h = new SHA1CryptoServiceProvider(); 68 | var b = c.GetDigestedOutput(h); 69 | var b64 = Convert.ToBase64String(b); 70 | 71 | var res = c.GetOutput() as MemoryStream; 72 | string s2 = System.Text.Encoding.UTF8.GetString(res.ToArray()); 73 | } 74 | }*/ 75 | } 76 | -------------------------------------------------------------------------------- /test/hmac-tests.spec.ts: -------------------------------------------------------------------------------- 1 | import { SignedXml } from "../src/index"; 2 | import * as xpath from "xpath"; 3 | import * as xmldom from "@xmldom/xmldom"; 4 | import * as fs from "fs"; 5 | import { expect } from "chai"; 6 | import * as isDomNode from "@xmldom/is-dom-node"; 7 | 8 | describe("HMAC tests", function () { 9 | it("test validating HMAC signature", function () { 10 | const xml = fs.readFileSync("./test/static/hmac_signature.xml", "utf-8"); 11 | const doc = new xmldom.DOMParser().parseFromString(xml); 12 | const signature = xpath.select1( 13 | "/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", 14 | doc, 15 | ); 16 | isDomNode.assertIsNodeLike(signature); 17 | 18 | const sig = new SignedXml(); 19 | sig.enableHMAC(); 20 | sig.publicCert = fs.readFileSync("./test/static/hmac.key"); 21 | sig.loadSignature(signature); 22 | const result = sig.checkSignature(xml); 23 | 24 | expect(result).to.be.true; 25 | expect(sig.getSignedReferences().length).to.equal(1); 26 | }); 27 | 28 | it("test HMAC signature with incorrect key", function () { 29 | const xml = fs.readFileSync("./test/static/hmac_signature.xml", "utf-8"); 30 | const doc = new xmldom.DOMParser().parseFromString(xml); 31 | const signature = xpath.select1( 32 | "/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", 33 | doc, 34 | ); 35 | isDomNode.assertIsNodeLike(signature); 36 | 37 | const sig = new SignedXml(); 38 | sig.enableHMAC(); 39 | sig.publicCert = fs.readFileSync("./test/static/hmac-foobar.key"); 40 | sig.loadSignature(signature); 41 | 42 | expect(() => sig.checkSignature(xml)).to.throw(/^invalid signature/); 43 | expect(sig.getSignedReferences().length).to.equal(0); 44 | }); 45 | 46 | it("test create and validate HMAC signature", function () { 47 | const xml = "" + "" + "Harry Potter" + "" + ""; 48 | const sig = new SignedXml(); 49 | sig.enableHMAC(); 50 | sig.privateKey = fs.readFileSync("./test/static/hmac.key"); 51 | sig.signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#hmac-sha1"; 52 | sig.addReference({ 53 | xpath: "//*[local-name(.)='book']", 54 | digestAlgorithm: "http://www.w3.org/2000/09/xmldsig#sha1", 55 | transforms: ["http://www.w3.org/2001/10/xml-exc-c14n#"], 56 | }); 57 | sig.canonicalizationAlgorithm = "http://www.w3.org/2001/10/xml-exc-c14n#"; 58 | sig.computeSignature(xml); 59 | 60 | const doc = new xmldom.DOMParser().parseFromString(sig.getSignedXml()); 61 | const signature = xpath.select1( 62 | "/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", 63 | doc, 64 | ); 65 | isDomNode.assertIsNodeLike(signature); 66 | 67 | const verify = new SignedXml(); 68 | verify.enableHMAC(); 69 | verify.publicCert = fs.readFileSync("./test/static/hmac.key"); 70 | verify.loadSignature(signature); 71 | const result = verify.checkSignature(sig.getSignedXml()); 72 | 73 | expect(result).to.be.true; 74 | expect(verify.getSignedReferences().length).to.equal(1); 75 | }); 76 | }); 77 | -------------------------------------------------------------------------------- /test/static/idp_private_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDXpgSoph176VQP 3 | w+4e91UAL6j0TbL/aI3Amj62TU91KOk4xigy+8xFSeU2IC64W7abfFq+25K+1ybJ 4 | mMBq94UKyKab7yeXmen2xJ9PT5br4TwnsbeBZrziXSR8uTE60DdWLZYJEBREgu96 5 | JeEWLzP/0HfnFlnuG5kXlb6rpy7l723YeDvU9lvsm6Rj46m5R8j4CSenKmLsHSIh 6 | mNP59SsEpJ16D+RfKcrKqxPxp6t/oCEKXjpmOeGoX9WT5V9UMxrGFgY2YLab9tLC 7 | IK48i6rgXpHUnbMq2XyAT58bSG/Tif99hoiQ2ovzsVUrVeCa4/uUg/pr+w1bZnIB 8 | l6R8WVPTVwgmYN+8Ww27aLiNksCn70t74XZLr9xnYnbnj324AiZp9Z48vDECm41T 9 | c+V9eqGNO/5YLgZqoGTy4El3AMcNF3lkecZ2UZKMI341pI1vHyRG0jCr2ZYpy30p 10 | YQKd+Z7AvZKMUTJFQfBIOn3zXN6SA8lWZLPOW4VTdOfcGjQij3AUDeTeilUigpRg 11 | kTl97WUrGfasvLXMrdRoXYxjGPe+s4+tf+gnKhTVQ6h6we+ISaFVOeXpCrOUwZM0 12 | OdikQtKYgH0G9OrJKxDZDl4YkkYFqqhyw5Eum9HZwMU8631lkBSqMRgz8AX7KdBn 13 | 1PrGS6wOp+GC28L1ISeRxRriWtaeXQIDAQABAoICAGhLJwKngCfu4xRS1mWMicPy 14 | yNwKffDPUIsfLgg94JlRhWXLVCLAK30xLVUdgGryFCEjpcGbcN+yL1SddyXkeqgJ 15 | /aX5pmTH7+LEGiYh4GRJBK5P4WeIV/6EPILDj/8ZN0IK/v54E81Eo+wnyLHRd20X 16 | lf2hjjG9kC9bYSEkVGapAq+ICqvG0BNg/MLAltOAV745sz9CHSCDQIAOKSrAuyLe 17 | ODkR2Yl6rVSSI62iQSuStpgMlWLeSHgFjUYfTxjqNF8rxKpk4LwSRcDUTGAEzkoA 18 | ArhY4o9tKqzllRX9VPPyUCmVuJOR1tCvaXjxahSPARvFLoYtnzqek7GYdNkc3JA8 19 | yMOnXAVfuJ6xML9gFQvCJ9qFL5ayVBi+2OSXpKX0O2AwIOqFilT8/QSoR6bJXMwJ 20 | R4VRtsUbvQ84wG7cRSmGpMWs+PrGOgO2JmjCeLPrSZXNUIYchxGun+nG1OlBMjTc 21 | GdEzUdC0BLwOuGpvTKtCMDvwXStogq1PtjCHvEfjX84jtlV3mvJFHnqIJBGkLQPX 22 | O9P2SVL3g8vNwuAKvfMtSgW2sUXf+nFBtiAFXqXdYy0vL3O4AAoWU8Jfl5EUbO1S 23 | bAGJcF5N9vsSFGDfcZzuAbbSdj6qUlIkncTBlVO/tWsdFIg9BXbH/qQZEaprX//P 24 | 5Z5wv+qBL353z7nCkb8zAoIBAQDrBQ8R49u/Pxupvr5pcFfZ14ifmIZnUar1bkig 25 | o/ylb6Si3WgQ5PP788snYp2R3kbo+JBrdyl/OQBWgtCKOXxFllrBjwlihDXnK+SB 26 | igqHCkKbjTMjI+Gkgot7sR+tC9UnM0SNHlX6fkWfbmj6dQIIv0Cd3yOzx/v+ml2w 27 | TUwxCfmroiX67y3Sl0yVAGmXfjQ1uRCLBiulJEfONAu6+it0H8Whtx5d9FglF2Hj 28 | ll+cOamAB+GZiJzAF6MucizS+Cfw+kWkrlOpFj2EqE7Z847Bhp1b6TSPCVZ+IUpY 29 | 1FTYIBw1JFe7xeRKsfHs0KgrpSf3AxuSalFfpLeV997+sd/3AoIBAQDq5kPnZZTT 30 | V/i+DCa3Q94gNNQC+6j1YE/PDaQeOS7ybYz6pFizrIn6ioIfKD1as8vViTnvw9kq 31 | CehnO+rOzPA4oloVFDNKqliLViJMz7CY8hRoiOUuLzGbsmTyqvjcSi39IOmWs7Pq 32 | YFE0vDftEimMCxLNuTP/JpSa1ZY9std0Ljkk9zBTAykkXrrmjUxvd938DMSOqAv/ 33 | Pnib/Oq5cumROMXpPaRMjvhc56iyfEyluTntpJREN9KHvtll8TrGmDk/WW8sF87t 34 | jmr0hNSa4dFOTkUS+EODL6BPKg+MwGN6UL7L811qztErKtFCK77JGr+dq66fU1bV 35 | y9JHSPYvJ8dLAoIBAQCnSUWNzWwoeEo/jCdLNA1EYXe9ajsZJfeTlXma5r86HvrI 36 | duLRS7cju0f68+YG43oD8JIT/JEMHs3PxnOcQAjmG3zkU+UxO7yGnSac0l5l+vao 37 | dFxXAf5mNAoG9HAAo/CIY6TC8jnvAJycPGH7DPhys3fSJ/foy0vi0Ywopwy5x0jx 38 | U4zHTiKGyO1ZDh8bF1kgeGd/HdhJR0bZTxCeed4eXVM2pfq2k+t+E2O5NNs/f4fY 39 | O0PpHmW9EdY0hE7FqJ/9lpel/fRM4ijN2WOvHf+aXzB5MMkZm2L2ism56wGtiUWq 40 | ygCtBtJWHM2AbJGX54pH9+1TTdw4QS3wUKxpDMHHAoIBAAcs9ZISBlPWciDMGjqq 41 | 9hQhyQA2U9j7EjUPA55wvMBnHFFjx9nlQWnH5WWyQv2MVIO3Z2+tmeqw1sqgh/G9 42 | TPFN9FaEgXScc4v+G5ohFhH2Ay2WUPnyMx/AeVj4ZBXGplT/NmOGJc7ZFmH4BfVW 43 | ArLme7KRH8eBlDSOpcJIvlAsQU6hxnYiuJUF18vHMTiOftd+RFrfQ06Ox/xr43e6 44 | zOvEwjb3zRcRnwCniv240laVq/FYf7b9xY6kA9wbXGJIsCcBQmYkbAvRt+60SBJb 45 | J5uuxGlp8BYH1GvWqxbvoZpQ8SMl0gq7OqSI8E+HKpLWIFhesDzpvNNXIJtQ3URf 46 | gLUCggEAa0SzoEaLut65B1mQuYaYXCvyXohRJn49BoHULUub/Zg2D+mPMJcyefBK 47 | o/FUZD8ewXUiEoj6eoEXHTT8eOSvhXQHp2dc6AW6rADzL4Ni0oSQ8LwT5fgGq7B7 48 | yxWXkSkK3T43RLvrb7FSV21WTcsXYH560LHa5me1S4Pb1Zrz8+KCRNdNcoffZMfi 49 | b09pdLkS7Sbiskg69NrOFmwfD8SdAb9opPLY5lLWEVtkaPwQS4MrboJJlDutV9VC 50 | /Ye8QbuMwKQHduhAGGsCpkEwZhO5T4owdebVeY28t80HsInv7mFuiqZbIN/BMnU7 51 | zvi/SKHNm+elLUD1r7tC3+KVTtqSSw== 52 | -----END PRIVATE KEY----- 53 | -------------------------------------------------------------------------------- /test/static/signature_with_inclusivenamespaces.xml: -------------------------------------------------------------------------------- 1 | http://www.okta.com/k7xkhq0jUHUPQAXVMUAN4G+uveKmtiB1EkY5BAt+8lmQwjI=Q80N6FUr5/YPtEzRlRdMoPu+bL0MssDxNUY+yxykzbmxsI0joEo/SmmSgZrDYQKTllZk/KfzBMPFV9yBH4+mEzCU5E3xuCs99jZzafcw3K8mIMTJy1YHxjc359d27R5s50i9w5PHsusRov0MjQIoJ2w48Gy4EnYaViqBR3UVEqE=MIICnTCCAgagAwIBAgIGAUBGHxqUMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYDVQQGEwJVUzETMBEG 2 | A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU 3 | MBIGA1UECwwLU1NPUHJvdmlkZXIxEjAQBgNVBAMMCWtsdWdsYWJzMjEcMBoGCSqGSIb3DQEJARYN 4 | aW5mb0Bva3RhLmNvbTAeFw0xMzA4MDMyMTM4MzhaFw00MzA4MDMyMTM5MzhaMIGRMQswCQYDVQQG 5 | EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UE 6 | CgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxEjAQBgNVBAMMCWtsdWdsYWJzMjEcMBoGCSqG 7 | SIb3DQEJARYNaW5mb0Bva3RhLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsCB9lJTH 8 | qB7vdM5jeOH84cW8u7IHYv4/OAPYF0fBYe9wJy19CgyM2OgiASuAcItnH4WhB+io2ZPwb/Xwl7Uu 9 | 4XmUE0l+mkCNuDYp5fXTZxwv5G6HvkAxXZio0Rk9T0VETCroxgpS5LxQ/o/owjR39S7xzRnj6ddX 10 | 3Mq2yGjKyBcCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAB1qGNqSNLLWq+RPcP+wOaWtYpJOJ8/MbZ 11 | EWWm9/KKHKXM6J/zgUUIXZi3czMeO+Y+X14PR8lGXoAHf5b/JavG9FmFvRn4fGa45VTVo2GfMN6K 12 | aIKF0obeCbYi/QUf8B+Xi1tSIJm1VCKRE7nnliQ/TzGaNulgWeyTbVkG0/X8LQ==admin@kluglabs.comhttps://auth0145.auth0.comurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransportAdmin -------------------------------------------------------------------------------- /test/static/signature_with_inclusivenamespaces_lines.xml: -------------------------------------------------------------------------------- 1 | http://www.okta.com/k7xkhq0jUHUPQAXVMUAN4G+uveKmtiB1EkY5BAt+8lmQwjI= 2 | 3 | Q80N6FUr5/YPtEzRlRdMoPu+bL0MssDxNUY+yxykzbmxsI0joEo/SmmSgZrDYQKTllZk/KfzBMPF 4 | V9yBH4+mEzCU5E3xuCs99jZzafcw3K8mIMTJy1YHxjc359d27R5s50i9w5PHsusRov0MjQIoJ2w4 5 | 8Gy4EnYaViqBR3UVEqE= 6 | 7 | 8 | MIICnTCCAgagAwIBAgIGAUBGHxqUMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYDVQQGEwJVUzETMBEG 9 | A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU 10 | MBIGA1UECwwLU1NPUHJvdmlkZXIxEjAQBgNVBAMMCWtsdWdsYWJzMjEcMBoGCSqGSIb3DQEJARYN 11 | aW5mb0Bva3RhLmNvbTAeFw0xMzA4MDMyMTM4MzhaFw00MzA4MDMyMTM5MzhaMIGRMQswCQYDVQQG 12 | EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UE 13 | CgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxEjAQBgNVBAMMCWtsdWdsYWJzMjEcMBoGCSqG 14 | SIb3DQEJARYNaW5mb0Bva3RhLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsCB9lJTH 15 | qB7vdM5jeOH84cW8u7IHYv4/OAPYF0fBYe9wJy19CgyM2OgiASuAcItnH4WhB+io2ZPwb/Xwl7Uu 16 | 4XmUE0l+mkCNuDYp5fXTZxwv5G6HvkAxXZio0Rk9T0VETCroxgpS5LxQ/o/owjR39S7xzRnj6ddX 17 | 3Mq2yGjKyBcCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAB1qGNqSNLLWq+RPcP+wOaWtYpJOJ8/MbZ 18 | EWWm9/KKHKXM6J/zgUUIXZi3czMeO+Y+X14PR8lGXoAHf5b/JavG9FmFvRn4fGa45VTVo2GfMN6K 19 | aIKF0obeCbYi/QUf8B+Xi1tSIJm1VCKRE7nnliQ/TzGaNulgWeyTbVkG0/X8LQ== 20 | admin@kluglabs.comhttps://auth0145.auth0.comurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransportAdmin -------------------------------------------------------------------------------- /test/static/signature_with_inclusivenamespaces_lines_windows.xml: -------------------------------------------------------------------------------- 1 | http://www.okta.com/k7xkhq0jUHUPQAXVMUAN4G+uveKmtiB1EkY5BAt+8lmQwjI= 2 | 3 | Q80N6FUr5/YPtEzRlRdMoPu+bL0MssDxNUY+yxykzbmxsI0joEo/SmmSgZrDYQKTllZk/KfzBMPF 4 | V9yBH4+mEzCU5E3xuCs99jZzafcw3K8mIMTJy1YHxjc359d27R5s50i9w5PHsusRov0MjQIoJ2w4 5 | 8Gy4EnYaViqBR3UVEqE= 6 | 7 | 8 | MIICnTCCAgagAwIBAgIGAUBGHxqUMA0GCSqGSIb3DQEBBQUAMIGRMQswCQYDVQQGEwJVUzETMBEG 9 | A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UECgwET2t0YTEU 10 | MBIGA1UECwwLU1NPUHJvdmlkZXIxEjAQBgNVBAMMCWtsdWdsYWJzMjEcMBoGCSqGSIb3DQEJARYN 11 | aW5mb0Bva3RhLmNvbTAeFw0xMzA4MDMyMTM4MzhaFw00MzA4MDMyMTM5MzhaMIGRMQswCQYDVQQG 12 | EwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzENMAsGA1UE 13 | CgwET2t0YTEUMBIGA1UECwwLU1NPUHJvdmlkZXIxEjAQBgNVBAMMCWtsdWdsYWJzMjEcMBoGCSqG 14 | SIb3DQEJARYNaW5mb0Bva3RhLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAsCB9lJTH 15 | qB7vdM5jeOH84cW8u7IHYv4/OAPYF0fBYe9wJy19CgyM2OgiASuAcItnH4WhB+io2ZPwb/Xwl7Uu 16 | 4XmUE0l+mkCNuDYp5fXTZxwv5G6HvkAxXZio0Rk9T0VETCroxgpS5LxQ/o/owjR39S7xzRnj6ddX 17 | 3Mq2yGjKyBcCAwEAATANBgkqhkiG9w0BAQUFAAOBgQAB1qGNqSNLLWq+RPcP+wOaWtYpJOJ8/MbZ 18 | EWWm9/KKHKXM6J/zgUUIXZi3czMeO+Y+X14PR8lGXoAHf5b/JavG9FmFvRn4fGa45VTVo2GfMN6K 19 | aIKF0obeCbYi/QUf8B+Xi1tSIJm1VCKRE7nnliQ/TzGaNulgWeyTbVkG0/X8LQ== 20 | admin@kluglabs.comhttps://auth0145.auth0.comurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransportAdmin 21 | -------------------------------------------------------------------------------- /test/utils-tests.spec.ts: -------------------------------------------------------------------------------- 1 | import * as fs from "fs"; 2 | import * as utils from "../src/utils"; 3 | import { expect } from "chai"; 4 | import * as xmldom from "@xmldom/xmldom"; 5 | import * as xpath from "xpath"; 6 | import * as isDomNode from "@xmldom/is-dom-node"; 7 | 8 | describe("Utils tests", function () { 9 | describe("derToPem", function () { 10 | it("will return a normalized PEM format when given an non-normalized PEM format", function () { 11 | const normalizedPem = fs.readFileSync("./test/static/client_public.pem", "latin1"); 12 | const pemAsArray = normalizedPem.trim().split("\n"); 13 | const base64String = pemAsArray.slice(1, -1).join(""); 14 | const nonNormalizedPem = `${pemAsArray[0]}\n${base64String}\n${ 15 | pemAsArray[pemAsArray.length - 1] 16 | }`; 17 | 18 | expect(utils.derToPem(nonNormalizedPem)).to.equal(normalizedPem); 19 | }); 20 | 21 | it("will return a normalized PEM format when given a base64 string", function () { 22 | const normalizedPem = fs.readFileSync("./test/static/client_public.pem", "latin1"); 23 | const pemAsArray = normalizedPem.trim().split("\n"); 24 | const base64String = pemAsArray.slice(1, -1).join(""); 25 | 26 | expect(utils.derToPem(base64String, "CERTIFICATE")).to.equal(normalizedPem); 27 | }); 28 | 29 | it("will throw if the format is neither PEM nor DER", function () { 30 | expect(() => utils.derToPem("not a pem")).to.throw(); 31 | }); 32 | 33 | it("will return a normalized PEM format when given a DER Buffer", function () { 34 | const normalizedPem = fs.readFileSync("./test/static/client_public.pem", "latin1"); 35 | const derBuffer = fs.readFileSync("./test/static/client_public.der"); 36 | 37 | expect(utils.derToPem(derBuffer, "CERTIFICATE")).to.equal(normalizedPem); 38 | }); 39 | 40 | it("will return a normalized PEM format when given a base64 string with line breaks", function () { 41 | const normalizedPem = fs.readFileSync("./test/static/client_public.pem", "latin1"); 42 | const base64String = fs.readFileSync("./test/static/client_public.der", "base64"); 43 | 44 | expect(utils.derToPem(base64String, "CERTIFICATE")).to.equal(normalizedPem); 45 | }); 46 | 47 | it("will return a normalized PEM format when given a base64 string with line breaks and spaces at the line breaks", function () { 48 | const xml = new xmldom.DOMParser().parseFromString( 49 | fs.readFileSync("./test/static/keyinfo - pretty-printed.xml", "latin1"), 50 | ); 51 | const cert = xpath.select1(".//*[local-name(.)='X509Certificate']", xml); 52 | isDomNode.assertIsNodeLike(cert); 53 | 54 | const normalizedPem = fs.readFileSync("./test/static/keyinfo.pem", "latin1"); 55 | 56 | expect(utils.derToPem(cert.textContent ?? "", "CERTIFICATE")).to.equal(normalizedPem); 57 | }); 58 | 59 | it("will throw if the DER string is not base64 encoded", function () { 60 | expect(() => utils.derToPem("not base64", "CERTIFICATE")).to.throw(); 61 | }); 62 | 63 | it("will throw if the PEM label is not provided", function () { 64 | const derBuffer = fs.readFileSync("./test/static/client_public.der"); 65 | expect(() => utils.derToPem(derBuffer)).to.throw(); 66 | }); 67 | }); 68 | 69 | describe("pemToDer", function () { 70 | it("will return a Buffer of binary DER when given a normalized PEM format", function () { 71 | const pem = fs.readFileSync("./test/static/client_public.pem", "latin1"); 72 | const derBuffer = fs.readFileSync("./test/static/client_public.der"); 73 | 74 | const result = utils.pemToDer(pem); 75 | expect(result).to.be.instanceOf(Buffer); 76 | expect(result).to.deep.equal(derBuffer); 77 | }); 78 | 79 | it("will throw if the format is not PEM", function () { 80 | expect(() => utils.pemToDer("not a pem")).to.throw(); 81 | }); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /test/static/client_bundle.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDCzCCAfMCFDdl3bSiEFLCBC3akD+sPuSbRKnyMA0GCSqGSIb3DQEBCwUAMEIx 3 | CzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0Rl 4 | ZmF1bHQgQ29tcGFueSBMdGQwHhcNMjMwNjE1MTAyNjMwWhcNMzMwNjEyMTAyNjMw 5 | WjBCMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQK 6 | DBNEZWZhdWx0IENvbXBhbnkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB 7 | CgKCAQEArMLLZkjvJ/Kr3rfhR/77nJdjPumutJ7lJoDgQAwG2qBmse4oJmBDB6fY 8 | XFTrwVH4DKYnJFOaPBAqp+BGpFEjKo/zghEcGxidnuM5Hc6NAfnK3YEmbspc1DGX 9 | cLCfv0Mw3VV+XvDxfLpQdfTA4CM/lgPmO6lUF6er/WaLsLMfJc2+jLXYkIlj+x6b 10 | KVNHC7SG/HkD0WSZAAsfW1RCOQgsgVi/b+TEPR7MqcXzS3R1WWd8dB9EC8VwpU3o 11 | KBZ4EaYYvbEH+z2YW24jl+vxGHM9+UZaoYMzkBnDs+gtmpH35S/+YFbrro+qbRAs 12 | Hy5FhhfQ0ZWbe9nAFUaID0CkemnQOwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBf 13 | gb5/f8Jv+zR5yD2VhaqZPgIc3lekCi1UxOrmSfnFZ1osSlgenf1dvJeCX9QEh2Lv 14 | FHmp0TflcJ12qHsWdfZSSantFhG5jMFxYD9uARyTHCWtRtdfO0P/KeuORleDN5lE 15 | p7wBCy6JpE5INQxoHYnhO0ujfo9SvZVxpBHRpdSnHrkKn+6UOr6HVFQ4RVyEns7B 16 | oZ/GQ7HWj4qpRF98MUmtwtCCemWPnNSjSAAWuJZ8e4JStjFcx8Vw3xIZbNGCZflw 17 | ECjO3qQDUQmzySBub8FaDZkG1d2ODZsL221ETto4c5DXlesgYBVcPIkQAy53IVoP 18 | hupmcqhjnIejGHsgFAdF 19 | -----END CERTIFICATE----- 20 | -----BEGIN CERTIFICATE----- 21 | MIIDZTCCAk2gAwIBAgIUD2FdlpUMPuX6W1A0OiMKu6g0XuYwDQYJKoZIhvcNAQEL 22 | BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE 23 | CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0yMzA2MTUxMDI2MDNaFw0zMzA2MTIx 24 | MDI2MDNaMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAa 25 | BgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IB 26 | DwAwggEKAoIBAQD/emWytGY9zUAJ8Jq++GgTieFkmdgwPq8QcHzfIhqs0n5Y28cS 27 | CExFwoNZaJQiA1lobD2bgwAJPUb4j1zUmnaKeDuc2dq3RhcctJ2kbReqJVwzPW19 28 | DxWsvADYrjzE6UdgyWZfoanp7IBKjEj3xF13w0rYm1D3lrT7mE5roEA10oOVwErl 29 | HgRcCO8nbWMxy6HnZmMiTY815xdWXVKZpbjNJaVybEEnW128BFafAy24XmMg5PLx 30 | YGLEVExO2RHjEOibDb08/L91wJA8N8rSDoG8Akl1UesdH95VBcMvK4lA2e4Nn2Lu 31 | vFkqtsey6YrNw4OD1uAnQ0hinuo7OlVMYiRLAgMBAAGjUzBRMB0GA1UdDgQWBBTD 32 | b17H/nXO5ZUh74YhBn/X7zZuxTAfBgNVHSMEGDAWgBTDb17H/nXO5ZUh74YhBn/X 33 | 7zZuxTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBsq1PBuJtg 34 | t+EFpbGngOmlMW4YaI77N8+H8Tk9+AIfvv+Awya+8T8ToMyEd7WZXuCabpzFwc5u 35 | TaZiHV0oyHNLLMt+QKrBZ9Ybu/RFJo0kjvbO2FEvtIiz9qqRqPUwD804HpXcyBvP 36 | lcQvJXRUSsaoTmcLtaA6TOWUbzxgHiXIDyiNVaM9B8hgKdqKCDqwtKYSAd9dpQVt 37 | Yq2yEXxLKrJjZRrRF0d5CesA4rOoUiRK7VnZSIo8aO8BtLH7UjOrFg5WFial/1kh 38 | SEmjbsPp6oLNyDtg4eTWkS82polPsCWihm9gEu3+plBQNXH7X6xrPEsn5ZilscCc 39 | +lxT6hClXBXJ 40 | -----END CERTIFICATE----- 41 | -----BEGIN PRIVATE KEY----- 42 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCswstmSO8n8qve 43 | t+FH/vucl2M+6a60nuUmgOBADAbaoGax7igmYEMHp9hcVOvBUfgMpickU5o8ECqn 44 | 4EakUSMqj/OCERwbGJ2e4zkdzo0B+crdgSZuylzUMZdwsJ+/QzDdVX5e8PF8ulB1 45 | 9MDgIz+WA+Y7qVQXp6v9Zouwsx8lzb6MtdiQiWP7HpspU0cLtIb8eQPRZJkACx9b 46 | VEI5CCyBWL9v5MQ9HsypxfNLdHVZZ3x0H0QLxXClTegoFngRphi9sQf7PZhbbiOX 47 | 6/EYcz35RlqhgzOQGcOz6C2akfflL/5gVuuuj6ptECwfLkWGF9DRlZt72cAVRogP 48 | QKR6adA7AgMBAAECggEAQVcvfNEq+u3yiTr8zrEm0vQDCmFxvUi3nJdzuWWTFg9C 49 | qBtOPi18TKHz2AAaZrSs34PcHAYuuHbY20OdFDrH1So6zD/SZIEr5FNGX/qmJFAo 50 | pRxav95zu6HCCFIVKU6tZZkXQatZenYxRlu6s0tBmmiBJKGHd6boCuBFByDIMBB/ 51 | P509g1TrRB70vAL8hqyd5wHJNhuwUvOOfLMfAMOXa5aAtwQlc0PXOUbUxwS3C4NW 52 | acqraGpFFWAOwg+J5eBi5jfXHDyiGhS5p8T8HkcoVyI5WrEQJES3fPlmA2IM8CXj 53 | 4ipS329zJNM8SUJuluo1KIJeFMNN5cF1DZqtREb38QKBgQDywatu2mOIAoN+cpwf 54 | VtTDH1qsGYxuCka+7tipt+DxTxIJB/1KTQRwdWb1leqszO3nNS6Q/UIDFMV+oszG 55 | 3UuoriOw+xuvYy/PrFdrDki3droipOEllSGmbXGk7rBalAbgswyF21ebgZi4moZr 56 | YjqdQl+R+XN1YjqnOn39njyeKQKBgQC2L5F90HBBhp+1qU1hbEGof5oMkp+Thjx/ 57 | PWbJsqt6s41yIemug3MP8QLlUOMG5X+QTCN4RNTmf60V5McF2TSuT8jbT8jby0w+ 58 | ClnZ9lgGMSL7UjI26CHkw36xcDH2hzgXWGRxzttzlXttJqnbeATHC811yWaLDXGU 59 | ecC7bG9/wwKBgQChgq8fgtdjv2BjObebtja6V1sJU7o14EpvcBPg30Ee65+xOIqR 60 | 66n/dGz7CjJno7TI9n4z4vwPdrtrZL9ftA5JfQqsDnW9+/zsa9qBlLBWt/xhXleZ 61 | nJ4Vz40j0datfP0SdK3pRSUFhnTopY63VVRwGp/hTBlASQmDB4yZt7TW+QKBgF73 62 | eM2ug3WEqWfWcsGf3rHoofJ/07LgvFRPO29UNVLmmYqu5tLTLn1W0n2apl0H8HDV 63 | X3/n0Vq9nwnUkXIZAP8EE91OP5Ni68FDQAcABG5l2qhK9mXspw5KYZY4t7KcVb7F 64 | ksZIX9hmSUpiZxRCAauIGXeWnl9JiLUuqiqIoa5lAoGAMS2HObavBhdTPkN998lq 65 | fnInmg5M466+PiPYZuQZh+Ea+8Gs0wv2wpFXw7Ds7hjo0hmiYGV/yw8etn45lpfA 66 | buAIy50HQABwOWxH74AzddemsUSFEnRO4VgQ2Cu2dDaDGRjZbXcggRtOZ+ynuUJi 67 | G9/7qOuw5oPSq0v7tEDbqpI= 68 | -----END PRIVATE KEY----- 69 | -------------------------------------------------------------------------------- /test/static/valid_signature_with_unused_prefixes.xml: -------------------------------------------------------------------------------- 1 | GAEFzMhRbXD8lZeTd5GwSqkB73Q=c2bqLRa0Q+/P7+vuXZHO8/iiac8=95WoCzf9J63UgdLCj/05PYaJIAw=pa04vRHbAdvfr6Re5wgx2qFQepE=YYNZUGNHN8uRGzMqPVC2n5XODP8=GvVowT6jH/4fExGYfFzDbzhSwTs=F8Lm5aUouA5FtxQ1krQ3unE9NFh0QSl+QscEyTcK3FrIpWCB195Z7cbmYa9RsiYMdr2wTHHmou/+wrjpk9pZFJq+b0tpHKCpfj6B302Rexb5f+cDpUjBB/NGb11qaUiM65keVIWzmYnHC0iCxsCaG3lwHMELNr7GxNun1U7LzzI=MIIBxDCCAW6gAwIBAgIQxUSXFzWJYYtOZnmmuOMKkjANBgkqhkiG9w0BAQQFADAWMRQwEgYDVQQDEwtSb290IEFnZW5jeTAeFw0wMzA3MDgxODQ3NTlaFw0zOTEyMzEyMzU5NTlaMB8xHTAbBgNVBAMTFFdTRTJRdWlja1N0YXJ0Q2xpZW50MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+L6aB9x928noY4+0QBsXnxkQE4quJl7c3PUPdVu7k9A02hRG481XIfWhrDY5i7OEB7KGW7qFJotLLeMec/UkKUwCgv3VvJrs2nE9xO3SSWIdNzADukYh+Cxt+FUU6tUkDeqg7dqwivOXhuOTRyOI3HqbWTbumaLdc8jufz2LhaQIDAQABo0swSTBHBgNVHQEEQDA+gBAS5AktBh0dTwCNYSHcFmRjoRgwFjEUMBIGA1UEAxMLUm9vdCBBZ2VuY3mCEAY3bACqAGSKEc+41KpcNfQwDQYJKoZIhvcNAQEEBQADQQAfIbnMPVYkNNfX1tG1F+qfLhHwJdfDUZuPyRPucWF5qkh6sSdWVBY5sT/txBnVJGziyO8DPYdu2fPMER8ajJfl2019-03-18T16:27:47.984Z2019-03-19T04:27:47.984Zhttp://www.example.com/testActionclientuuid:c519e597-0570-4d35-92e5-0df733a17cc1testtestMessage -------------------------------------------------------------------------------- /test/validators/XmlCryptoUtilities/XmlCryptoUtilities/Program.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This example signs an XML file using an 3 | // envelope signature. It then verifies the 4 | // signed XML. 5 | // 6 | using System; 7 | using System.Security.Cryptography; 8 | using System.Security.Cryptography.X509Certificates; 9 | using System.Security.Cryptography.Xml; 10 | using System.Text; 11 | using System.Xml; 12 | using System.IO; 13 | using System.Reflection; 14 | 15 | public class SignVerifyEnvelope 16 | { 17 | 18 | public static void Main(String[] args) 19 | { 20 | var exe = Assembly.GetExecutingAssembly().Location; 21 | var folder = Path.GetDirectoryName(exe); 22 | var pfx = Path.Combine(folder, "ClientPrivate.pfx"); 23 | var c = new X509Certificate2(File.ReadAllBytes(pfx), "wse2qs"); 24 | 25 | if (args[0] == "verify") 26 | { 27 | Console.WriteLine("verifying signature..."); 28 | var file = Path.Combine(folder, "SignedExample.xml"); 29 | bool b = VerifyXmlFile(file, (RSA)c.PublicKey.Key); 30 | Console.WriteLine("signature is " + (b ? "valid" : "not valid!")); 31 | if (!b) Environment.Exit(-1); 32 | } 33 | else if (args[0] == "sign") 34 | { 35 | Console.WriteLine("generating signature..."); 36 | var xmlFile = Path.Combine(folder, "Example.xml"); 37 | var sigFile = Path.Combine(folder, "signedExample.xml"); 38 | CreateSomeXml(xmlFile); 39 | SignXmlFile(xmlFile, sigFile, (RSA)c.PrivateKey); 40 | Console.WriteLine("done"); 41 | } 42 | } 43 | 44 | // Sign an XML file and save the signature in a new file. This method does not 45 | // save the public key within the XML file. This file cannot be verified unless 46 | // the verifying code has the key with which it was signed. 47 | public static void SignXmlFile(string FileName, string SignedFileName, RSA Key) 48 | { 49 | // Create a new XML document. 50 | XmlDocument doc = new XmlDocument(); 51 | 52 | // Load the passed XML file using its name. 53 | doc.Load(new XmlTextReader(FileName)); 54 | 55 | // Create a SignedXml object. 56 | SignedXml signedXml = new SignedXml(doc); 57 | 58 | // Add the key to the SignedXml document. 59 | signedXml.SigningKey = Key; 60 | 61 | // Create a reference to be signed. 62 | Reference reference = new Reference(); 63 | reference.Uri = ""; 64 | 65 | // Add an enveloped transformation to the reference. 66 | XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); 67 | reference.AddTransform(env); 68 | 69 | // Add the reference to the SignedXml object. 70 | signedXml.AddReference(reference); 71 | 72 | // Compute the signature. 73 | signedXml.ComputeSignature(); 74 | 75 | // Get the XML representation of the signature and save 76 | // it to an XmlElement object. 77 | XmlElement xmlDigitalSignature = signedXml.GetXml(); 78 | 79 | // Append the element to the XML document. 80 | doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); 81 | 82 | if (doc.FirstChild is XmlDeclaration) 83 | { 84 | doc.RemoveChild(doc.FirstChild); 85 | } 86 | 87 | // Save the signed XML document to a file specified 88 | // using the passed string. 89 | XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false)); 90 | doc.WriteTo(xmltw); 91 | xmltw.Close(); 92 | } 93 | 94 | // Verify the signature of an XML file against an asymetric 95 | // algorithm and return the result. 96 | public static Boolean VerifyXmlFile(String Name, RSA Key) 97 | { 98 | // Create a new XML document. 99 | XmlDocument xmlDocument = new XmlDocument(); 100 | 101 | // Load the passed XML file into the document. 102 | xmlDocument.Load(Name); 103 | 104 | // Create a new SignedXml object and pass it 105 | // the XML document class. 106 | SignedXml signedXml = new SignedXml(xmlDocument); 107 | 108 | // Find the "Signature" node and create a new 109 | // XmlNodeList object. 110 | XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature"); 111 | 112 | // Load the signature node. 113 | signedXml.LoadXml((XmlElement)nodeList[0]); 114 | 115 | // Check the signature and return the result. 116 | return signedXml.CheckSignature(Key); 117 | } 118 | 119 | 120 | // Create example data to sign. 121 | public static void CreateSomeXml(string FileName) 122 | { 123 | // Create a new XmlDocument object. 124 | XmlDocument document = new XmlDocument(); 125 | 126 | // Create a new XmlNode object. 127 | XmlNode node = document.CreateNode(XmlNodeType.Element, "", "MyElement", "samples"); 128 | 129 | // Add some text to the node. 130 | node.InnerText = "Example text to be signed."; 131 | 132 | // Append the node to the document. 133 | document.AppendChild(node); 134 | 135 | // Save the XML document to the file name specified. 136 | XmlTextWriter xmltw = new XmlTextWriter(FileName, new UTF8Encoding(false)); 137 | document.WriteTo(xmltw); 138 | xmltw.Close(); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /test/static/saml_external_ns.xml: -------------------------------------------------------------------------------- 1 | https://app.onelogin.com/saml/metadata/164679https://app.onelogin.com/saml/metadata/164679Gx0mTydMn1k6804jZBrdUrZmbV4=oHEPKtwoCbfq1QRm2pjx35zVMqAsti4nQU+3ws8EUJUXHmPG2EoX3HBkb7D2wN4m+ZFrdwARUpNJlhhOIz/eG4jES6ar0tvlNN3qE5cqcQhwZHyRARLnTlERqyZU9Qm729DnAGBeXCdMb736zi16onOIVPNA63LRTzUIxhyZqypDCf1wd6me/ur6UUgH11nYOu4JDYx0iWNkXc1Nad7vkF9oMPeO1QsMxuZSIVH4tvdJkue+qAnu2l+dFJb0LPfm+xmIC0FBo+VX1ECCWRoUZIxjotQfAM6yZpHIi5fNqPXkVyN9fYoUEa9CafqHlc4tAAdgAgGeOqA3jWeC8ZnOVA==MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbTAeFw0xMzA1MjcwODU1MTNaFw0xODA1MjcwODU1MTNaMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9uZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoXoc7IFZQRv+SwJ15zjIl9touwY5e6b7H4vn3OtOUByjOKHUX8VX0TpbAV2ctZE2GSALx1AGuQAv6O4MVUH+qn/2IAiBY3a7zKN07UBsya7xFMQVHuGE6EiBAs9jpA9wjvYMPRkS5wYZcwjpTQSZK7zFPPtobG8K/1vDbm/tWZjNLmZmQePmXpwrQAuC0+NlzlmnjoQYB2xp2NaTUK9JnnmuB5qev3dpUwlYGSJpf+HUIoxuo8IpxAXOymq1d6tEEJgU1kR2sa7o1sSRFo31YeW/qYCP/gcLJZo3MRUDFe0g5MHeliFue9DsKYUsC6qwAD3gc+MI47buiD6Msu11cwIDAQABo4HUMIHRMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFAAJFJRIlpQQSFsuNdeq7FkTJIH4MIGRBgNVHSMEgYkwgYaAFAAJFJRIlpQQSFsuNdeq7FkTJIH4oWukaTBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbYIBATAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADggEBAB9zN+g6N4sUBE61RaMUH2LSHWwOtfhL64i7pjHjvZa47/qcV/S0Yyd4IE44ho9i2N+AM79d34mThc30oK5aVxOKphKf+xM/cOyVaWIeqr+dCbkY/0OpLEwWOh9VSgOizRO3evLMurbtR892LbSK/Td3hG5jfwoHD23nHH87Dv/3KyZox9MkJdY2DXOHGGIcsqoIifaTyNZyhW6RgwEujQ6LjsaolP1YoeV85TZFKTLa1Ta7ZLUVUC2UJWqz+kRlsyGxf+E/ZmJ7hSq0ZBVHrVOyXjCcFn6X0/W5SrpOmN3fZYcj8Bp6vhB0cJk9qpjgWOP2RCuBdHZVawjCjIaE+bc=kartik.cds@gmail.comForNodeJSurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransportkartik.cds@gmail.comKartikCDS -------------------------------------------------------------------------------- /test/validators/XmlCryptoJava/src/test/java/org/nodejs/xmlcrypto/HMACTest.java: -------------------------------------------------------------------------------- 1 | package org.nodejs.xmlcrypto; 2 | 3 | import java.io.File; 4 | import java.util.Collections; 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | import javax.crypto.KeyGenerator; 8 | import javax.crypto.SecretKey; 9 | import javax.xml.crypto.dsig.CanonicalizationMethod; 10 | import javax.xml.crypto.dsig.DigestMethod; 11 | import javax.xml.crypto.dsig.Reference; 12 | import javax.xml.crypto.dsig.SignatureMethod; 13 | import javax.xml.crypto.dsig.SignedInfo; 14 | import javax.xml.crypto.dsig.Transform; 15 | import javax.xml.crypto.dsig.XMLSignature; 16 | import javax.xml.crypto.dsig.XMLSignatureFactory; 17 | import javax.xml.crypto.dsig.dom.DOMSignContext; 18 | import javax.xml.crypto.dsig.keyinfo.KeyInfo; 19 | import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory; 20 | import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec; 21 | import javax.xml.parsers.DocumentBuilder; 22 | import javax.xml.parsers.DocumentBuilderFactory; 23 | import javax.xml.transform.Transformer; 24 | import javax.xml.transform.TransformerFactory; 25 | import javax.xml.transform.dom.DOMSource; 26 | import javax.xml.transform.stream.StreamResult; 27 | import org.apache.commons.io.FileUtils; 28 | import org.junit.Test; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | import org.w3c.dom.Document; 32 | import org.w3c.dom.Element; 33 | import org.w3c.dom.Node; 34 | 35 | public class HMACTest { 36 | 37 | public static final String NamespaceSpecNS = "http://www.w3.org/2000/xmlns/"; 38 | 39 | private static final Logger LOGGER = LoggerFactory 40 | .getLogger(HMACTest.class); 41 | 42 | @Test 43 | public void testCreateHMACSignature() throws Exception { 44 | // generate key 45 | KeyGenerator keyGenerator = KeyGenerator.getInstance("HmacSHA1"); 46 | SecretKey secretKey = keyGenerator.generateKey(); 47 | 48 | // generate DOM document 49 | DocumentBuilderFactory documentBuilderFactory 50 | = DocumentBuilderFactory.newInstance(); 51 | documentBuilderFactory.setNamespaceAware(true); 52 | DocumentBuilder documentBuilder = documentBuilderFactory 53 | .newDocumentBuilder(); 54 | Document document = documentBuilder.newDocument(); 55 | Element rootElement = document.createElementNS("urn:test", 56 | "test:Root"); 57 | rootElement.setAttributeNS(NamespaceSpecNS, 58 | "xmlns:test", "urn:test"); 59 | document.appendChild(rootElement); 60 | 61 | XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory 62 | .getInstance("DOM"); 63 | 64 | // XML Signature references 65 | List references = new LinkedList<>(); 66 | List transforms = new LinkedList<>(); 67 | Transform envTransform = xmlSignatureFactory.newTransform( 68 | CanonicalizationMethod.ENVELOPED, 69 | (C14NMethodParameterSpec) null); 70 | transforms.add(envTransform); 71 | Transform exclTransform = xmlSignatureFactory.newTransform( 72 | CanonicalizationMethod.EXCLUSIVE, 73 | (C14NMethodParameterSpec) null); 74 | transforms.add(exclTransform); 75 | Reference reference = xmlSignatureFactory.newReference("", 76 | xmlSignatureFactory.newDigestMethod(DigestMethod.SHA256, 77 | null), transforms, null, null); 78 | references.add(reference); 79 | 80 | // XML Signature SignedInfo 81 | SignedInfo signedInfo = xmlSignatureFactory.newSignedInfo( 82 | xmlSignatureFactory.newCanonicalizationMethod( 83 | CanonicalizationMethod.EXCLUSIVE, 84 | (C14NMethodParameterSpec) null), 85 | xmlSignatureFactory.newSignatureMethod( 86 | SignatureMethod.HMAC_SHA1, 87 | null), references); 88 | 89 | // XML Signature KeyInfo 90 | KeyInfoFactory keyInfoFactory 91 | = xmlSignatureFactory.getKeyInfoFactory(); 92 | KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections 93 | .singletonList(keyInfoFactory.newKeyName("some-key-name"))); 94 | 95 | Element parentElement = document.getDocumentElement(); 96 | DOMSignContext domSignContext = new DOMSignContext( 97 | secretKey, parentElement); 98 | domSignContext.setDefaultNamespacePrefix("ds"); 99 | XMLSignature xmlSignature = xmlSignatureFactory.newXMLSignature( 100 | signedInfo, keyInfo); 101 | xmlSignature.sign(domSignContext); 102 | 103 | File tmpFile = File.createTempFile("xml-signature-hmac-", ".xml"); 104 | LOGGER.debug("XML signature file: {}", tmpFile.getAbsolutePath()); 105 | toFile(document, tmpFile); 106 | 107 | File tmpKeyFile = File.createTempFile("hmac-", ".key"); 108 | FileUtils.writeByteArrayToFile(tmpKeyFile, secretKey.getEncoded()); 109 | LOGGER.debug("key file: {}", tmpKeyFile.getAbsolutePath()); 110 | 111 | } 112 | 113 | private void toFile(Node node, File file) throws Exception { 114 | TransformerFactory transformerFactory = TransformerFactory 115 | .newInstance(); 116 | Transformer transformer = transformerFactory.newTransformer(); 117 | transformer.transform(new DOMSource(node), new StreamResult(file)); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /test/static/keyinfo - pretty-printed.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://evil-corp.com 4 | 5 | 6 | uAP/VBhhaK2+Bn1lYjHB5tSHTcE=Q2F/63pvENmI+eURRIRmVI1fNpW+CxDan6YmGo2G5il+XOx72sBHS+FspoWDyezYUfO/Wfi+tBupK 7 | /9eHOeg60uPUkQFwkdPmUsH2hJAPVCatQReSUJDhHCO6a2rrQixecPDBhzJjstCpibgvgNzevVVu 8 | 9h3eMH/BNzdwO5EbnVTcb2JQj2F18MAh1LlVMBWWDaZmIQTk7npMY/NVEajM1fbwXyrPdNRU8poK 9 | bjVoM7IL9s0TesQIeyQ01QOQQQ3kHZWnoqlWE6VbbTqHwuidfkqaQLLvF9sDneqXKBa7y2YEJXVm4 10 | GMzNoL/JOdSuNnU3rF0ET8UDSleV953/lbUA== 11 | MIIDtTCCAp2gAwIBAgIJAKg4VeVcIDz1MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAlVTMRMwE 12 | QYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMT 13 | UwODEzMDE1NDIwWhcNMTUwOTEyMDE1NDIwWjBFMQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1 14 | TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEF 15 | AAOCAQ8AMIIBCgKCAQEAxG3ouM7U+fXbJt69X1H6d4UNg/uRr06pFuU9RkfIwNC+yaXyptqB3ynXK 16 | sL7BFt4DCd0fflRvJAx3feJIDp16wN9GDVHcufWMYPhh2j5HcTW/j9JoIJzGhJyvO00YKBt+hHy83 17 | iN1SdChKv5y0iSyiPP5GnqFw+ayyHoM6hSO0PqBou1Xb0ZSIE+DHosBnvVna5w2AiPY4xrJl9yZHZ 18 | 4Q7DfMiYTgstjETio4bX+6oLiBnYktn7DjdEslqhffVme4PuBxNojI+uCeg/sn4QVLd/iogMJfDWN 19 | uLD8326Mi/FE9cCRvFlvAiMSaebMI3zPaySsxTK7Zgj5TpEbmbHI9wIDAQABo4GnMIGkMB0GA1UdD 20 | gQWBBSVGgvoW4MhMuzBGce29PY8vSzHFzB1BgNVHSMEbjBsgBSVGgvoW4MhMuzBGce29PY8vSzHF6 21 | FJpEcwRTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV 22 | 0IFdpZGdpdHMgUHR5IEx0ZIIJAKg4VeVcIDz1MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD 23 | ggEBAJu1rqs+anD74dbdwgd3CnqnQsQDJiEXmBhG2leaGt3ve9b/9gKaJg2pyb2NyppDe1uLqh6nN 24 | XDuzg1oNZrPz5pJL/eCXPl7FhxhMUi04TtLf8LeNTCIWYZiFuO4pmhohHcv8kRvYR1+6SkLTC8j/T 25 | Zerm7qvesSiTQFNapa1eNdVQ8nFwVkEtWl+JzKEM1BlRcn42sjJkijeFp7DpI7pU+PnYeiaXpRv5p 26 | Jo8ogM1iFxN+SnfEs0EuQ7fhKIG9aHKi7bKZ7L6SyX7MDIGLeulEU6lf5D9BfXNmcMambiS0pXhL2 27 | QXajt96UBq8FT2KNXY8XNtR4y6MyyCzhaiZZcc8= 28 | 29 | 30 | 31 | 32 | https://evil-corp.com 33 | 34 | vincent.vega@evil-corp.com 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport 44 | 45 | 46 | 47 | 48 | 49 | 50 | vincent.vega@evil-corp.com 51 | 52 | 53 | 54 | Vincent 55 | 56 | 57 | 58 | VEGA 59 | 60 | 61 | 62 | 123 Main St. 63 | Suite 11 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/signature-algorithms.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from "crypto"; 2 | import { type SignatureAlgorithm, createOptionalCallbackFunction } from "./types"; 3 | 4 | export class RsaSha1 implements SignatureAlgorithm { 5 | getSignature = createOptionalCallbackFunction( 6 | (signedInfo: crypto.BinaryLike, privateKey: crypto.KeyLike): string => { 7 | const signer = crypto.createSign("RSA-SHA1"); 8 | signer.update(signedInfo); 9 | const res = signer.sign(privateKey, "base64"); 10 | 11 | return res; 12 | }, 13 | ); 14 | 15 | verifySignature = createOptionalCallbackFunction( 16 | (material: string, key: crypto.KeyLike, signatureValue: string): boolean => { 17 | const verifier = crypto.createVerify("RSA-SHA1"); 18 | verifier.update(material); 19 | const res = verifier.verify(key, signatureValue, "base64"); 20 | 21 | return res; 22 | }, 23 | ); 24 | 25 | getAlgorithmName = () => { 26 | return "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; 27 | }; 28 | } 29 | 30 | export class RsaSha256 implements SignatureAlgorithm { 31 | getSignature = createOptionalCallbackFunction( 32 | (signedInfo: crypto.BinaryLike, privateKey: crypto.KeyLike): string => { 33 | const signer = crypto.createSign("RSA-SHA256"); 34 | signer.update(signedInfo); 35 | const res = signer.sign(privateKey, "base64"); 36 | 37 | return res; 38 | }, 39 | ); 40 | 41 | verifySignature = createOptionalCallbackFunction( 42 | (material: string, key: crypto.KeyLike, signatureValue: string): boolean => { 43 | const verifier = crypto.createVerify("RSA-SHA256"); 44 | verifier.update(material); 45 | const res = verifier.verify(key, signatureValue, "base64"); 46 | 47 | return res; 48 | }, 49 | ); 50 | 51 | getAlgorithmName = () => { 52 | return "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; 53 | }; 54 | } 55 | 56 | export class RsaSha256Mgf1 implements SignatureAlgorithm { 57 | getSignature = createOptionalCallbackFunction( 58 | (signedInfo: crypto.BinaryLike, privateKey: crypto.KeyLike): string => { 59 | if (!(typeof privateKey === "string" || Buffer.isBuffer(privateKey))) { 60 | throw new Error("keys must be strings or buffers"); 61 | } 62 | const signer = crypto.createSign("RSA-SHA256"); 63 | signer.update(signedInfo); 64 | const res = signer.sign( 65 | { 66 | key: privateKey, 67 | padding: crypto.constants.RSA_PKCS1_PSS_PADDING, 68 | saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST, 69 | }, 70 | "base64", 71 | ); 72 | 73 | return res; 74 | }, 75 | ); 76 | 77 | verifySignature = createOptionalCallbackFunction( 78 | (material: string, key: crypto.KeyLike, signatureValue: string): boolean => { 79 | if (!(typeof key === "string" || Buffer.isBuffer(key))) { 80 | throw new Error("keys must be strings or buffers"); 81 | } 82 | const verifier = crypto.createVerify("RSA-SHA256"); 83 | verifier.update(material); 84 | const res = verifier.verify( 85 | { 86 | key: key, 87 | padding: crypto.constants.RSA_PKCS1_PSS_PADDING, 88 | saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST, 89 | }, 90 | signatureValue, 91 | "base64", 92 | ); 93 | 94 | return res; 95 | }, 96 | ); 97 | 98 | getAlgorithmName = () => { 99 | return "http://www.w3.org/2007/05/xmldsig-more#sha256-rsa-MGF1"; 100 | }; 101 | } 102 | 103 | export class RsaSha512 implements SignatureAlgorithm { 104 | getSignature = createOptionalCallbackFunction( 105 | (signedInfo: crypto.BinaryLike, privateKey: crypto.KeyLike): string => { 106 | const signer = crypto.createSign("RSA-SHA512"); 107 | signer.update(signedInfo); 108 | const res = signer.sign(privateKey, "base64"); 109 | 110 | return res; 111 | }, 112 | ); 113 | 114 | verifySignature = createOptionalCallbackFunction( 115 | (material: string, key: crypto.KeyLike, signatureValue: string): boolean => { 116 | const verifier = crypto.createVerify("RSA-SHA512"); 117 | verifier.update(material); 118 | const res = verifier.verify(key, signatureValue, "base64"); 119 | 120 | return res; 121 | }, 122 | ); 123 | 124 | getAlgorithmName = () => { 125 | return "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"; 126 | }; 127 | } 128 | 129 | export class HmacSha1 implements SignatureAlgorithm { 130 | getSignature = createOptionalCallbackFunction( 131 | (signedInfo: crypto.BinaryLike, privateKey: crypto.KeyLike): string => { 132 | const signer = crypto.createHmac("SHA1", privateKey); 133 | signer.update(signedInfo); 134 | const res = signer.digest("base64"); 135 | 136 | return res; 137 | }, 138 | ); 139 | 140 | verifySignature = createOptionalCallbackFunction( 141 | (material: string, key: crypto.KeyLike, signatureValue: string): boolean => { 142 | const verifier = crypto.createHmac("SHA1", key); 143 | verifier.update(material); 144 | const res = verifier.digest("base64"); 145 | 146 | // Use constant-time comparison to prevent timing attacks (CWE-208) 147 | // See: https://github.com/node-saml/xml-crypto/issues/522 148 | try { 149 | return crypto.timingSafeEqual( 150 | Buffer.from(res, "base64"), 151 | Buffer.from(signatureValue, "base64"), 152 | ); 153 | } catch (e) { 154 | // timingSafeEqual throws if buffer lengths don't match 155 | return false; 156 | } 157 | }, 158 | ); 159 | 160 | getAlgorithmName = () => { 161 | return "http://www.w3.org/2000/09/xmldsig#hmac-sha1"; 162 | }; 163 | } 164 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Basic Options */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | "target": "es2020" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */, 8 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */, 9 | "lib": ["es2020"] /* Specify library files to be included in the compilation. */, 10 | "allowJs": true /* Allow javascript files to be compiled. */, 11 | // "checkJs": true, /* Report errors in .js files. */ 12 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 13 | "declaration": true /* Generates corresponding '.d.ts' file. */, 14 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 15 | "sourceMap": true /* Generates corresponding '.map' file. */, 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | "outDir": "./lib" /* Redirect output structure to the directory. */, 18 | "rootDir": "./src" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */, 19 | // "composite": true, /* Enable project compilation */ 20 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 21 | // "removeComments": true, /* Do not emit comments to output. */ 22 | // "noEmit": true, /* Do not emit outputs. */ 23 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 24 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 25 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 26 | 27 | /* Strict Type-Checking Options */ 28 | "strict": true /* Enable all strict type-checking options. */, 29 | "noImplicitAny": false /* Raise error on expressions and declarations with an implied 'any' type. */, 30 | // "strictNullChecks": true, /* Enable strict null checks. */ 31 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 32 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 33 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 34 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 35 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 36 | 37 | /* Additional Checks */ 38 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 39 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 40 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 41 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 42 | 43 | /* Module Resolution Options */ 44 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 45 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 46 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 47 | // "typeRoots": [], /* List of folders to include type definitions from. */ 48 | // "types": [], /* Type declaration files to be included in compilation. */ 49 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 50 | // "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 51 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 52 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 53 | 54 | /* Source Map Options */ 55 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 56 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 57 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 58 | "inlineSources": true /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */, 59 | 60 | /* Experimental Options */ 61 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 62 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 63 | 64 | /* Advanced Options */ 65 | "skipLibCheck": true /* Skip type checking of declaration files. */, 66 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 67 | }, 68 | "exclude": ["node_modules", "docs", "lib", "test", "coverage", "example"], 69 | "include": ["src"] 70 | } 71 | -------------------------------------------------------------------------------- /test/static/valid_saml_sha256_rsa_mgf1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | bA/90zzLS/36DstvPJRrMNwGax5WQv8NneSuNdLnMYs= 12 | 13 | 14 | 15 | 0fK5rJEtj0+JIL3hAuDsEAuKYoiwHzZTgQgspLyEe+XQan1FzT+qu3GBJSpSDfArBHjHXtizVfi8 16 | irId6a1kOj6ShEw2ZSGYD8Dh2d0HmrHqlOqpZ5eLiWeFA6VTtW1Cqmvr+x4Ndxcg0wWmmGr4hpSD 17 | Yg8fkA8e32Fd2QxqLsQqVlCcuvJVCJ/12XSGcMW+Tse254fN6JENLLUdilu+14NNQKAHpKpjeajg 18 | jG3fn0VNvyVQXKi2deYTWYaLRujBgv3Ncz8t9Hjthk+XxrRVHJiGc6HyVvqdpi5ChM41fjB1+eBo 19 | NkZ0Q73ZSCbTAqVduUWqL5pQzINq16kUm2ovkg7h3JoqSQr5yhoBJXZEf6FEyYdCCLd3rlIrkcvD 20 | +wfF2CwNRc6utgO/05JAA7Z1x2e0K6o2a6EQy93dkUIBhpxPYU/IdmGb15AfKJ3OrB1K/jTrxZ2q 21 | og/u0fJe0vU1sL4EDOXqVMj/unTZqDP/K1mOHK/eDWafs/IwMv65ebZUwTk74AMk/oOYV9mL8beY 22 | JAVYMN+xPA1cXnHlRgwATWLXjfiQcMXo44nhaw0YlOUGIoRLYURqHmXz0W3d8pXYdybLmdClkqLR 23 | vo1ryK1OC2paYG9qwk51QJ5wzMv6HRB5tDIL9/7mP7khlKgm4p+EZXFGYmvYDbk2x219SvxPmfY= 24 | 25 | 26 | 27 | 28 | 29 | 16YEqKYde+lUD8PuHvdVAC+o9E2y/2iNwJo+tk1PdSjpOMYoMvvMRUnlNiAuuFu2m3xavtuSvtcm 30 | yZjAaveFCsimm+8nl5np9sSfT0+W6+E8J7G3gWa84l0kfLkxOtA3Vi2WCRAURILveiXhFi8z/9B3 31 | 5xZZ7huZF5W+q6cu5e9t2Hg71PZb7JukY+OpuUfI+Aknpypi7B0iIZjT+fUrBKSdeg/kXynKyqsT 32 | 8aerf6AhCl46ZjnhqF/Vk+VfVDMaxhYGNmC2m/bSwiCuPIuq4F6R1J2zKtl8gE+fG0hv04n/fYaI 33 | kNqL87FVK1XgmuP7lIP6a/sNW2ZyAZekfFlT01cIJmDfvFsNu2i4jZLAp+9Le+F2S6/cZ2J25499 34 | uAImafWePLwxApuNU3PlfXqhjTv+WC4GaqBk8uBJdwDHDRd5ZHnGdlGSjCN+NaSNbx8kRtIwq9mW 35 | Kct9KWECnfmewL2SjFEyRUHwSDp981zekgPJVmSzzluFU3Tn3Bo0Io9wFA3k3opVIoKUYJE5fe1l 36 | Kxn2rLy1zK3UaF2MYxj3vrOPrX/oJyoU1UOoesHviEmhVTnl6QqzlMGTNDnYpELSmIB9BvTqySsQ 37 | 2Q5eGJJGBaqocsORLpvR2cDFPOt9ZZAUqjEYM/AF+ynQZ9T6xkusDqfhgtvC9SEnkcUa4lrWnl0= 38 | 39 | AQAB 40 | 41 | 42 | 43 | 44 | MIIFFzCCAv+gAwIBAgIUaAU88KUbZLe7NwTw+jdCHIDU6wIwDQYJKoZIhvcNAQELBQAwGjEYMBYG 45 | A1UEAwwPaWRwLmV4YW1wbGUuY29tMCAXDTI1MDkwODExMTUzMFoYDzIxMjUwODE1MTExNTMwWjAa 46 | MRgwFgYDVQQDDA9pZHAuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC 47 | AQDXpgSoph176VQPw+4e91UAL6j0TbL/aI3Amj62TU91KOk4xigy+8xFSeU2IC64W7abfFq+25K+ 48 | 1ybJmMBq94UKyKab7yeXmen2xJ9PT5br4TwnsbeBZrziXSR8uTE60DdWLZYJEBREgu96JeEWLzP/ 49 | 0HfnFlnuG5kXlb6rpy7l723YeDvU9lvsm6Rj46m5R8j4CSenKmLsHSIhmNP59SsEpJ16D+RfKcrK 50 | qxPxp6t/oCEKXjpmOeGoX9WT5V9UMxrGFgY2YLab9tLCIK48i6rgXpHUnbMq2XyAT58bSG/Tif99 51 | hoiQ2ovzsVUrVeCa4/uUg/pr+w1bZnIBl6R8WVPTVwgmYN+8Ww27aLiNksCn70t74XZLr9xnYnbn 52 | j324AiZp9Z48vDECm41Tc+V9eqGNO/5YLgZqoGTy4El3AMcNF3lkecZ2UZKMI341pI1vHyRG0jCr 53 | 2ZYpy30pYQKd+Z7AvZKMUTJFQfBIOn3zXN6SA8lWZLPOW4VTdOfcGjQij3AUDeTeilUigpRgkTl9 54 | 7WUrGfasvLXMrdRoXYxjGPe+s4+tf+gnKhTVQ6h6we+ISaFVOeXpCrOUwZM0OdikQtKYgH0G9OrJ 55 | KxDZDl4YkkYFqqhyw5Eum9HZwMU8631lkBSqMRgz8AX7KdBn1PrGS6wOp+GC28L1ISeRxRriWtae 56 | XQIDAQABo1MwUTAdBgNVHQ4EFgQULRbUCREu3zQABqNW8LMOfraF5BMwHwYDVR0jBBgwFoAULRbU 57 | CREu3zQABqNW8LMOfraF5BMwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAA6Jm 58 | 3pll7XHBY/oXrtRAu60RpH4pcZBSf68zhCQKUnXALy2FWrUGU8uVCJJuxXIcxszTOCZmwVF12Yce 59 | IFpBrWHxKCDZWYDO6hrwZvsa2vh5mXDZo3c/HX6GmJR4f4oIIZnbxFhXR30419PlrwMW3Rk7rnVS 60 | Dz/HpQfdS4y8jYgsm2dIRo+PXQytFRCDj4afsT3eZa27QjFxLTuK+SwkhupSH1WWYmqL9+iIJiLL 61 | /ntfM4MwtOUwcfqI0ttbvFZZIPneBCuEDLn/zJ/QBV3ZvjQDt53W21HaPGPHBBfVZVroZPvuGvul 62 | WRLeECI1Hmbl3al/2aOC0LWzPIk8dlTcN+EWcCEufpTOEgkob8waEyxlX0Z5OBjkCHpyDTPGkxBB 63 | OCJv88Frx7qdbu8eSV0OviuaM/B7ky2NbDMKIybX4tf/Q8FNfjPLvTv+8nbrMz6kTno3RR2YC7tt 64 | I7Glb/eOg3F/ouF4wcoPAj+OyU5Q5WJMMaZ9cXF9pwszsglLbFms+WD5PFxlloh6I1hO7TccWKTe 65 | UJ5fYZSYYm31JqWit3DBltXTyRyL7KFSdT/FyRBk62YLCJqJmcukIUJUTya73/RmjW1M4zMBNaIj 66 | /pH77opKWnVbm9F4XnBCG4r9+FRXdV2zKW6DgvDzQ6DaZ+0cwC36vSqkDyjZYv/tviuWfM8= 67 | 68 | 69 | 70 | 71 | https://idp.example.com/ 72 | 73 | 74 | 75 | 76 | https://idp.example.com/ 77 | 78 | nameId 79 | 80 | 81 | 82 | 83 | 84 | 85 | audience 86 | 87 | 88 | 89 | 90 | urn:oasis:names:tc:SAML:2.0:ac:classes:Password 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /test/static/invalid_saml_sha256_rsa_mgf1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | bA/90zzLS/36DstvPJRrMNwGax5WQv8NneSuNdLnMYs= 12 | 13 | 14 | 15 | 0fK5rJEtj0+JIL3hAuDsEAuKYoiwHzZTgQgspLyEe+XQan1FzT+qu3GBJSpSDfArBHjHXtizVfi8 16 | irId6a1kOj6ShEw2ZSGYD8Dh2d0HmrHqlOqpZ5eLiWeFA6VTtW1Cqmvr+x4Ndxcg0wWmmGr4hpSD 17 | Yg8fkA8e32Fd2QxqLsQqVlCcuvJVCJ/12XSGcMW+Tse254fN6JENLLUdilu+14NNQKAHpKpjeajg 18 | jG3fn0VNvyVQXKi2deYTWYaLRujBgv3Ncz8t9Hjthk+XxrRVHJiGc6HyVvqdpi5ChM41fjB1+eBo 19 | NkZ0Q73ZSCbTAqVduUWqL5pQzINq16kUm2ovkg7h3JoqSQr5yhoBJXZEf6FEyYdCCLd3rlIrkcvD 20 | +wfF2CwNRc6utgO/05JAA7Z1x2e0K6o2a6EQy93dkUIBhpxPYU/IdmGb15AfKJ3OrB1K/jTrxZ2q 21 | og/u0fJe0vU1sL4EDOXqVMj/unTZqDP/K1mOHK/eDWafs/IwMv65ebZUwTk74AMk/oOYV9mL8beY 22 | JAVYMN+xPA1cXnHlRgwATWLXjfiQcMXo44nhaw0YlOUGIoRLYURqHmXz0W3d8pXYdybLmdClkqLR 23 | vo1ryK1OC2paYG9qwk51QJ5wzMv6HRB5tDIL9/7mP7khlKgm4p+EZXFGYmvYDbk2x219SvxPmfY= 24 | 25 | 26 | 27 | 28 | 29 | 16YEqKYde+lUD8PuHvdVAC+o9E2y/2iNwJo+tk1PdSjpOMYoMvvMRUnlNiAuuFu2m3xavtuSvtcm 30 | yZjAaveFCsimm+8nl5np9sSfT0+W6+E8J7G3gWa84l0kfLkxOtA3Vi2WCRAURILveiXhFi8z/9B3 31 | 5xZZ7huZF5W+q6cu5e9t2Hg71PZb7JukY+OpuUfI+Aknpypi7B0iIZjT+fUrBKSdeg/kXynKyqsT 32 | 8aerf6AhCl46ZjnhqF/Vk+VfVDMaxhYGNmC2m/bSwiCuPIuq4F6R1J2zKtl8gE+fG0hv04n/fYaI 33 | kNqL87FVK1XgmuP7lIP6a/sNW2ZyAZekfFlT01cIJmDfvFsNu2i4jZLAp+9Le+F2S6/cZ2J25499 34 | uAImafWePLwxApuNU3PlfXqhjTv+WC4GaqBk8uBJdwDHDRd5ZHnGdlGSjCN+NaSNbx8kRtIwq9mW 35 | Kct9KWECnfmewL2SjFEyRUHwSDp981zekgPJVmSzzluFU3Tn3Bo0Io9wFA3k3opVIoKUYJE5fe1l 36 | Kxn2rLy1zK3UaF2MYxj3vrOPrX/oJyoU1UOoesHviEmhVTnl6QqzlMGTNDnYpELSmIB9BvTqySsQ 37 | 2Q5eGJJGBaqocsORLpvR2cDFPOt9ZZAUqjEYM/AF+ynQZ9T6xkusDqfhgtvC9SEnkcUa4lrWnl0= 38 | 39 | AQAB 40 | 41 | 42 | 43 | 44 | MIIFFzCCAv+gAwIBAgIUaAU88KUbZLe7NwTw+jdCHIDU6wIwDQYJKoZIhvcNAQELBQAwGjEYMBYG 45 | A1UEAwwPaWRwLmV4YW1wbGUuY29tMCAXDTI1MDkwODExMTUzMFoYDzIxMjUwODE1MTExNTMwWjAa 46 | MRgwFgYDVQQDDA9pZHAuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC 47 | AQDXpgSoph176VQPw+4e91UAL6j0TbL/aI3Amj62TU91KOk4xigy+8xFSeU2IC64W7abfFq+25K+ 48 | 1ybJmMBq94UKyKab7yeXmen2xJ9PT5br4TwnsbeBZrziXSR8uTE60DdWLZYJEBREgu96JeEWLzP/ 49 | 0HfnFlnuG5kXlb6rpy7l723YeDvU9lvsm6Rj46m5R8j4CSenKmLsHSIhmNP59SsEpJ16D+RfKcrK 50 | qxPxp6t/oCEKXjpmOeGoX9WT5V9UMxrGFgY2YLab9tLCIK48i6rgXpHUnbMq2XyAT58bSG/Tif99 51 | hoiQ2ovzsVUrVeCa4/uUg/pr+w1bZnIBl6R8WVPTVwgmYN+8Ww27aLiNksCn70t74XZLr9xnYnbn 52 | j324AiZp9Z48vDECm41Tc+V9eqGNO/5YLgZqoGTy4El3AMcNF3lkecZ2UZKMI341pI1vHyRG0jCr 53 | 2ZYpy30pYQKd+Z7AvZKMUTJFQfBIOn3zXN6SA8lWZLPOW4VTdOfcGjQij3AUDeTeilUigpRgkTl9 54 | 7WUrGfasvLXMrdRoXYxjGPe+s4+tf+gnKhTVQ6h6we+ISaFVOeXpCrOUwZM0OdikQtKYgH0G9OrJ 55 | KxDZDl4YkkYFqqhyw5Eum9HZwMU8631lkBSqMRgz8AX7KdBn1PrGS6wOp+GC28L1ISeRxRriWtae 56 | XQIDAQABo1MwUTAdBgNVHQ4EFgQULRbUCREu3zQABqNW8LMOfraF5BMwHwYDVR0jBBgwFoAULRbU 57 | CREu3zQABqNW8LMOfraF5BMwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAA6Jm 58 | 3pll7XHBY/oXrtRAu60RpH4pcZBSf68zhCQKUnXALy2FWrUGU8uVCJJuxXIcxszTOCZmwVF12Yce 59 | IFpBrWHxKCDZWYDO6hrwZvsa2vh5mXDZo3c/HX6GmJR4f4oIIZnbxFhXR30419PlrwMW3Rk7rnVS 60 | Dz/HpQfdS4y8jYgsm2dIRo+PXQytFRCDj4afsT3eZa27QjFxLTuK+SwkhupSH1WWYmqL9+iIJiLL 61 | /ntfM4MwtOUwcfqI0ttbvFZZIPneBCuEDLn/zJ/QBV3ZvjQDt53W21HaPGPHBBfVZVroZPvuGvul 62 | WRLeECI1Hmbl3al/2aOC0LWzPIk8dlTcN+EWcCEufpTOEgkob8waEyxlX0Z5OBjkCHpyDTPGkxBB 63 | OCJv88Frx7qdbu8eSV0OviuaM/B7ky2NbDMKIybX4tf/Q8FNfjPLvTv+8nbrMz6kTno3RR2YC7tt 64 | I7Glb/eOg3F/ouF4wcoPAj+OyU5Q5WJMMaZ9cXF9pwszsglLbFms+WD5PFxlloh6I1hO7TccWKTe 65 | UJ5fYZSYYm31JqWit3DBltXTyRyL7KFSdT/FyRBk62YLCJqJmcukIUJUTya73/RmjW1M4zMBNaIj 66 | /pH77opKWnVbm9F4XnBCG4r9+FRXdV2zKW6DgvDzQ6DaZ+0cwC36vSqkDyjZYv/tviuWfM8= 67 | 68 | 69 | 70 | 71 | https://idp.example.com/ 72 | 73 | 74 | 75 | 76 | https://idp.example.com/ 77 | 78 | modifiedFakeNameId 79 | 80 | 81 | 82 | 83 | 84 | 85 | audience 86 | 87 | 88 | 89 | 90 | urn:oasis:names:tc:SAML:2.0:ac:classes:Password 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /test/static/valid_saml_with_digest_comment.xml: -------------------------------------------------------------------------------- 1 | https://openidp.feide.no 2 | https://openidp.feide.no 3 | 4 | 5 | RnNjoyUguwze5w2R+cboyTHlkQk=aw5711jKP7xragunjRRCAD4mT4xKHc37iohBpQDbdSomD3ksOSB96UZQp0MtaC3xlVSkMtYw85Om96T2q2xrxLLYVA50eFJEMMF7SCVPStWTVjBlaCuOPEQxIaHyJs9Sy3MCEfbBh4Pqn9IJBd1kzwdlCrWWjAmksbFFg5wHQJA= 6 | MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==test@example.compassport-samlurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordbergieHenriBergiusHenri Bergiushenri.bergius@nemein.combergie@rnd.feide.no8216c78fe244502efa13f62e6615c94acb7bdf3ebergieHenriBergiusHenri Bergiushenri.bergius@nemein.combergie@rnd.feide.no8216c78fe244502efa13f62e6615c94acb7bdf3e 7 | -------------------------------------------------------------------------------- /test/document-tests.spec.ts: -------------------------------------------------------------------------------- 1 | import { SignedXml } from "../src/index"; 2 | import * as xpath from "xpath"; 3 | import * as xmldom from "@xmldom/xmldom"; 4 | import * as fs from "fs"; 5 | import { expect } from "chai"; 6 | import * as isDomNode from "@xmldom/is-dom-node"; 7 | 8 | describe("Document tests", function () { 9 | it("test with a document (using FileKeyInfo)", function () { 10 | const xml = fs.readFileSync("./test/static/valid_saml.xml", "utf-8"); 11 | const doc = new xmldom.DOMParser().parseFromString(xml); 12 | const node = xpath.select1( 13 | "/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", 14 | doc, 15 | ); 16 | 17 | isDomNode.assertIsNodeLike(node); 18 | const sig = new SignedXml(); 19 | sig.publicCert = fs.readFileSync("./test/static/feide_public.pem"); 20 | sig.loadSignature(node); 21 | const result = sig.checkSignature(xml); 22 | 23 | expect(result).to.be.true; 24 | expect(sig.getSignedReferences().length).to.equal(1); 25 | }); 26 | 27 | it("test with a document (using StringKeyInfo)", function () { 28 | const xml = fs.readFileSync("./test/static/valid_saml.xml", "utf-8"); 29 | const doc = new xmldom.DOMParser().parseFromString(xml); 30 | const node = xpath.select1( 31 | "/*/*[local-name(.)='Signature' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", 32 | doc, 33 | ); 34 | 35 | isDomNode.assertIsNodeLike(node); 36 | const sig = new SignedXml(); 37 | const feidePublicCert = fs.readFileSync("./test/static/feide_public.pem"); 38 | sig.publicCert = feidePublicCert; 39 | sig.loadSignature(node); 40 | const result = sig.checkSignature(xml); 41 | 42 | expect(result).to.be.true; 43 | expect(sig.getSignedReferences().length).to.equal(1); 44 | }); 45 | }); 46 | 47 | describe("Validated node references tests", function () { 48 | it("should return references if the document is validly signed", function () { 49 | const xml = fs.readFileSync("./test/static/valid_saml.xml", "utf-8"); 50 | const doc = new xmldom.DOMParser().parseFromString(xml); 51 | const sig = new SignedXml(); 52 | sig.getCertFromKeyInfo = SignedXml.getCertFromKeyInfo; 53 | sig.loadSignature(sig.findSignatures(doc)[0]); 54 | const validSignature = sig.checkSignature(xml); 55 | expect(validSignature).to.be.true; 56 | expect(sig.getSignedReferences().length).to.equal(1); 57 | 58 | /* eslint-disable-next-line deprecation/deprecation */ 59 | const ref = sig.getReferences()[0]; 60 | const result = ref.getValidatedNode(); 61 | expect(result?.toString()).to.equal(doc.toString()); 62 | expect(sig.getSignedReferences().length).to.equal(1); 63 | }); 64 | 65 | it("should not return references if the document is not validly signed", function () { 66 | const xml = fs.readFileSync("./test/static/invalid_signature - changed content.xml", "utf-8"); 67 | const doc = new xmldom.DOMParser().parseFromString(xml); 68 | const sig = new SignedXml(); 69 | sig.loadSignature(sig.findSignatures(doc)[0]); 70 | const validSignature = sig.checkSignature(xml); 71 | expect(validSignature).to.be.false; 72 | expect(sig.getSignedReferences().length).to.equal(0); 73 | 74 | /* eslint-disable-next-line deprecation/deprecation */ 75 | const ref = sig.getReferences()[1]; 76 | const result = ref.getValidatedNode(); 77 | expect(result).to.be.null; 78 | expect(sig.getSignedReferences().length).to.equal(0); 79 | }); 80 | 81 | it("should return `null` if the selected node isn't found", function () { 82 | const xml = fs.readFileSync("./test/static/valid_saml.xml", "utf-8"); 83 | const doc = new xmldom.DOMParser().parseFromString(xml); 84 | const sig = new SignedXml(); 85 | sig.getCertFromKeyInfo = SignedXml.getCertFromKeyInfo; 86 | sig.loadSignature(sig.findSignatures(doc)[0]); 87 | const validSignature = sig.checkSignature(xml); 88 | expect(validSignature).to.be.true; 89 | expect(sig.getSignedReferences().length).to.equal(1); 90 | 91 | /* eslint-disable-next-line deprecation/deprecation */ 92 | const ref = sig.getReferences()[0]; 93 | const result = ref.getValidatedNode("/non-existent-node"); 94 | expect(result).to.be.null; 95 | }); 96 | 97 | it("should return the selected node if it is validly signed", function () { 98 | const xml = fs.readFileSync("./test/static/valid_saml.xml", "utf-8"); 99 | const doc = new xmldom.DOMParser().parseFromString(xml); 100 | const sig = new SignedXml(); 101 | sig.getCertFromKeyInfo = SignedXml.getCertFromKeyInfo; 102 | sig.loadSignature(sig.findSignatures(doc)[0]); 103 | const validSignature = sig.checkSignature(xml); 104 | expect(validSignature).to.be.true; 105 | expect(sig.getSignedReferences().length).to.equal(1); 106 | 107 | /* eslint-disable-next-line deprecation/deprecation */ 108 | const ref = sig.getReferences()[0]; 109 | const result = ref.getValidatedNode( 110 | "//*[local-name()='Attribute' and @Name='mail']/*[local-name()='AttributeValue']/text()", 111 | ); 112 | expect(result?.nodeValue).to.equal("henri.bergius@nemein.com"); 113 | expect(sig.getSignedReferences().length).to.equal(1); 114 | }); 115 | 116 | it("should return `null` if the selected node isn't validly signed", function () { 117 | const xml = fs.readFileSync("./test/static/invalid_signature - changed content.xml", "utf-8"); 118 | const doc = new xmldom.DOMParser().parseFromString(xml); 119 | const sig = new SignedXml(); 120 | sig.loadSignature(sig.findSignatures(doc)[0]); 121 | const validSignature = sig.checkSignature(xml); 122 | expect(validSignature).to.be.false; 123 | expect(sig.getSignedReferences().length).to.equal(0); 124 | 125 | /* eslint-disable-next-line deprecation/deprecation */ 126 | const ref = sig.getReferences()[0]; 127 | const result = ref.getValidatedNode( 128 | "//*[local-name()='Attribute' and @Name='mail']/*[local-name()='AttributeValue']/text()", 129 | ); 130 | expect(result).to.be.null; 131 | // Not all references verified, so no references should be in `.getSignedReferences()`. 132 | expect(sig.getSignedReferences().length).to.equal(0); 133 | }); 134 | }); 135 | -------------------------------------------------------------------------------- /test/static/invalid_saml_no_signed_info.xml: -------------------------------------------------------------------------------- 1 | https://openidp.feide.no 2 | 3 | 4 | dkONrkxW+LSuDvnNMG/mWYFa47d2WGyapLhXSTYqrlT9Td+tT7ciojNJ55WTaPaCMt7IrGtIxxskPAZIjdIn5pRyDxHr0joWxzZ7oZHCOI1CnQV5HjOq+rzzmEN2LctCZ6S4hbL7SQ1qJ3vp2BCXAygy4tmJOURQdnk0KLwwRS8= 5 | MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==https://openidp.feide.no 6 | 7 | 8 | RnNjoyUguwze5w2R+cboyTHlkQk=aw5711jKP7xragunjRRCAD4mT4xKHc37iohBpQDbdSomD3ksOSB96UZQp0MtaC3xlVSkMtYw85Om96T2q2xrxLLYVA50eFJEMMF7SCVPStWTVjBlaCuOPEQxIaHyJs9Sy3MCEfbBh4Pqn9IJBd1kzwdlCrWWjAmksbFFg5wHQJA= 9 | MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==_6c5dcaa3053321ff4d63785fbc3f67c59a129cde82passport-samlurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordbergieHenriBergiusHenri Bergiushenri.bergius@nemein.combergie@rnd.feide.no8216c78fe244502efa13f62e6615c94acb7bdf3ebergieHenriBergiusHenri Bergiushenri.bergius@nemein.combergie@rnd.feide.no8216c78fe244502efa13f62e6615c94acb7bdf3e -------------------------------------------------------------------------------- /test/static/valid_saml.xml: -------------------------------------------------------------------------------- 1 | https://openidp.feide.no 2 | 3 | 4 | fc21hh1bKZpaMNjx9HfOfVelfWw=dkONrkxW+LSuDvnNMG/mWYFa47d2WGyapLhXSTYqrlT9Td+tT7ciojNJ55WTaPaCMt7IrGtIxxskPAZIjdIn5pRyDxHr0joWxzZ7oZHCOI1CnQV5HjOq+rzzmEN2LctCZ6S4hbL7SQ1qJ3vp2BCXAygy4tmJOURQdnk0KLwwRS8= 5 | MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==https://openidp.feide.no 6 | 7 | 8 | RnNjoyUguwze5w2R+cboyTHlkQk=aw5711jKP7xragunjRRCAD4mT4xKHc37iohBpQDbdSomD3ksOSB96UZQp0MtaC3xlVSkMtYw85Om96T2q2xrxLLYVA50eFJEMMF7SCVPStWTVjBlaCuOPEQxIaHyJs9Sy3MCEfbBh4Pqn9IJBd1kzwdlCrWWjAmksbFFg5wHQJA= 9 | MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==_6c5dcaa3053321ff4d63785fbc3f67c59a129cde82passport-samlurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordbergieHenriBergiusHenri Bergiushenri.bergius@nemein.combergie@rnd.feide.no8216c78fe244502efa13f62e6615c94acb7bdf3ebergieHenriBergiusHenri Bergiushenri.bergius@nemein.combergie@rnd.feide.no8216c78fe244502efa13f62e6615c94acb7bdf3e 10 | -------------------------------------------------------------------------------- /test/static/valid_saml_withcomments.xml: -------------------------------------------------------------------------------- 1 | https://openidp.feide.no 2 | 3 | 4 | fc21hh1bKZpaMNjx9HfOfVelfWw=dkONrkxW+LSuDvnNMG/mWYFa47d2WGyapLhXSTYqrlT9Td+tT7ciojNJ55WTaPaCMt7IrGtIxxskPAZIjdIn5pRyDxHr0joWxzZ7oZHCOI1CnQV5HjOq+rzzmEN2LctCZ6S4hbL7SQ1qJ3vp2BCXAygy4tmJOURQdnk0KLwwRS8= 5 | MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==https://openidp.feide.no 6 | 7 | 8 | RnNjoyUguwze5w2R+cboyTHlkQk=aw5711jKP7xragunjRRCAD4mT4xKHc37iohBpQDbdSomD3ksOSB96UZQp0MtaC3xlVSkMtYw85Om96T2q2xrxLLYVA50eFJEMMF7SCVPStWTVjBlaCuOPEQxIaHyJs9Sy3MCEfbBh4Pqn9IJBd1kzwdlCrWWjAmksbFFg5wHQJA= 9 | MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==_6c5dcaa3053321ff4d63785fbc3f67c59a129cde82passport-samlurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordbergieHenriBergiusHenri Bergiushenri.bergius@nemein.combergie@rnd.feide.no8216c78fe244502efa13f62e6615c94acb7bdf3ebergieHenriBergiusHenri Bergiushenri.bergius@nemein.combergie@rnd.feide.no8216c78fe244502efa13f62e6615c94acb7bdf3e 10 | -------------------------------------------------------------------------------- /test/static/valid_saml_signature_wrapping.xml: -------------------------------------------------------------------------------- 1 | https://openidp.feide.no 2 | 3 | https://openidp.feide.no 4 | 5 | 6 | RnNjoyUguwze5w2R+cboyTHlkQk=aw5711jKP7xragunjRRCAD4mT4xKHc37iohBpQDbdSomD3ksOSB96UZQp0MtaC3xlVSkMtYw85Om96T2q2xrxLLYVA50eFJEMMF7SCVPStWTVjBlaCuOPEQxIaHyJs9Sy3MCEfbBh4Pqn9IJBd1kzwdlCrWWjAmksbFFg5wHQJA= 7 | MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==_6c5dcaa3053321ff4d63785fbc3f67c59a129cde82passport-samlurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordbergieHenriBergiusHenri Bergiushenri.bergius@nemein.combergie@rnd.feide.no8216c78fe244502efa13f62e6615c94acb7bdf3ebergieHenriBergiusHenri Bergiushenri.bergius@nemein.combergie@rnd.feide.no8216c78fe244502efa13f62e6615c94acb7bdf3e 8 | 9 | https://openidp.feide.no 10 | 11 | 12 | RnNjoyUguwze5w2R+cboyTHlkQk=aw5711jKP7xragunjRRCAD4mT4xKHc37iohBpQDbdSomD3ksOSB96UZQp0MtaC3xlVSkMtYw85Om96T2q2xrxLLYVA50eFJEMMF7SCVPStWTVjBlaCuOPEQxIaHyJs9Sy3MCEfbBh4Pqn9IJBd1kzwdlCrWWjAmksbFFg5wHQJA= 13 | MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8xEjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVpZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJlYXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VOSU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkwJwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATANBgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXChpye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w== 14 | ================ 15 | This Assertion contains malicious data. 16 | ================ 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/static/saml_wrapped_signed_info_node.xml: -------------------------------------------------------------------------------- 1 | https://app.onelogin.com/saml/metadata/164679https://app.onelogin.com/saml/metadata/164679jGst6BnAC9xOeqa6hKNPsoMm2TY=Gx0mTydMn1k6804jZBrdUrZmbV4=oHEPKtwoCbfq1QRm2pjx35zVMqAsti4nQU+3ws8EUJUXHmPG2EoX3HBkb7D2wN4m+ZFrdwARUpNJlhhOIz/eG4jES6ar0tvlNN3qE5cqcQhwZHyRARLnTlERqyZU9Qm729DnAGBeXCdMb736zi16onOIVPNA63LRTzUIxhyZqypDCf1wd6me/ur6UUgH11nYOu4JDYx0iWNkXc1Nad7vkF9oMPeO1QsMxuZSIVH4tvdJkue+qAnu2l+dFJb0LPfm+xmIC0FBo+VX1ECCWRoUZIxjotQfAM6yZpHIi5fNqPXkVyN9fYoUEa9CafqHlc4tAAdgAgGeOqA3jWeC8ZnOVA==MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbTAeFw0xMzA1MjcwODU1MTNaFw0xODA1MjcwODU1MTNaMGcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRUwEwYDVQQHDAxTYW50YSBNb25pY2ExETAPBgNVBAoMCE9uZUxvZ2luMRkwFwYDVQQDDBBhcHAub25lbG9naW4uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoXoc7IFZQRv+SwJ15zjIl9touwY5e6b7H4vn3OtOUByjOKHUX8VX0TpbAV2ctZE2GSALx1AGuQAv6O4MVUH+qn/2IAiBY3a7zKN07UBsya7xFMQVHuGE6EiBAs9jpA9wjvYMPRkS5wYZcwjpTQSZK7zFPPtobG8K/1vDbm/tWZjNLmZmQePmXpwrQAuC0+NlzlmnjoQYB2xp2NaTUK9JnnmuB5qev3dpUwlYGSJpf+HUIoxuo8IpxAXOymq1d6tEEJgU1kR2sa7o1sSRFo31YeW/qYCP/gcLJZo3MRUDFe0g5MHeliFue9DsKYUsC6qwAD3gc+MI47buiD6Msu11cwIDAQABo4HUMIHRMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFAAJFJRIlpQQSFsuNdeq7FkTJIH4MIGRBgNVHSMEgYkwgYaAFAAJFJRIlpQQSFsuNdeq7FkTJIH4oWukaTBnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMU2FudGEgTW9uaWNhMREwDwYDVQQKDAhPbmVMb2dpbjEZMBcGA1UEAwwQYXBwLm9uZWxvZ2luLmNvbYIBATAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADggEBAB9zN+g6N4sUBE61RaMUH2LSHWwOtfhL64i7pjHjvZa47/qcV/S0Yyd4IE44ho9i2N+AM79d34mThc30oK5aVxOKphKf+xM/cOyVaWIeqr+dCbkY/0OpLEwWOh9VSgOizRO3evLMurbtR892LbSK/Td3hG5jfwoHD23nHH87Dv/3KyZox9MkJdY2DXOHGGIcsqoIifaTyNZyhW6RgwEujQ6LjsaolP1YoeV85TZFKTLa1Ta7ZLUVUC2UJWqz+kRlsyGxf+E/ZmJ7hSq0ZBVHrVOyXjCcFn6X0/W5SrpOmN3fZYcj8Bp6vhB0cJk9qpjgWOP2RCuBdHZVawjCjIaE+bc=anyone@gmail.comForNodeJSurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransportkartik.cds@gmail.comKartikCDShttps://app.onelogin.com/saml/metadata/164679kartik.cds@gmail.comForNodeJSurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransportkartik.cds@gmail.comKartikCDS --------------------------------------------------------------------------------