├── .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
--------------------------------------------------------------------------------