Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: auth0/node-xml-encryption
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.2.3
Choose a base ref
...
head repository: auth0/node-xml-encryption
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.

Commits on Mar 17, 2021

  1. Copy the full SHA
    ca3796b View commit details

Commits on Apr 22, 2021

  1. Copy the full SHA
    1688a90 View commit details
  2. release 1.2.4

    Contains minor dependency updates
    gkwang committed Apr 22, 2021
    Copy the full SHA
    93937fd View commit details

Commits on Apr 23, 2021

  1. Merge pull request #85 from gkwang/1.2.4

    release 1.2.4
    lzychowski authored Apr 23, 2021
    Copy the full SHA
    e89e7fc View commit details

Commits on Aug 24, 2021

  1. Update xmldom to 0.7.0 (#88)

    The package is now scoped under @xmldom. See xmldom/xmldom#278
    This fixes security vulnerability CVE-2021-32796
    forty authored Aug 24, 2021
    Copy the full SHA
    7b360cd View commit details
  2. release 1.3.0

    npm audit changes
    gkwang committed Aug 24, 2021
    Copy the full SHA
    3c742bf View commit details

Commits on Aug 25, 2021

  1. Merge pull request #89 from auth0/1.3.0

    release 1.3.0
    esarafianou authored Aug 25, 2021
    Copy the full SHA
    f5f6532 View commit details

Commits on Jan 13, 2022

  1. Replace node-forge by native node crypto.

    This requires dropping support for node 8, which is probably fine since
    node 8 is EoL since December 31, 2019.
    forty committed Jan 13, 2022
    Copy the full SHA
    7aaa734 View commit details
  2. Merge pull request #86 from forty/forty/remove-node-forge

    Replace node-forge by native node crypto.
    esarafianou authored Jan 13, 2022
    Copy the full SHA
    291f3f1 View commit details

Commits on Jan 14, 2022

  1. release 2.0.0

    Also updates package lock file to version 2; backwards compatible to
    version 1
    Eva Sarafianou committed Jan 14, 2022
    Copy the full SHA
    77ccf3b View commit details

Commits on Jan 19, 2022

  1. Merge pull request #95 from auth0/release_v2

    release 2.0.0
    esarafianou authored Jan 19, 2022
    Copy the full SHA
    28cc6f1 View commit details

Commits on Apr 12, 2022

  1. Copy the full SHA
    e8df80c View commit details

Commits on Oct 13, 2022

  1. fix: package.json & package-lock.json to reduce vulnerabilities (#100)

    The following vulnerabilities are fixed with an upgrade:
    - https://snyk.io/vuln/SNYK-JS-XMLDOMXMLDOM-3042243
    snyk-bot authored Oct 13, 2022
    Copy the full SHA
    3457a9b View commit details

Commits on Oct 17, 2022

  1. Copy the full SHA
    d59bb6c View commit details

Commits on Oct 18, 2022

  1. release 3.0.0 (#104)

    add semgrep support
    uodate xmldom
    breaking changes in xmldom:
    xmldom/xmldom#310
    xmldom/xmldom#314
    xmldom/xmldom#307
    gkwang authored Oct 18, 2022
    Copy the full SHA
    6ae0fcd View commit details

Commits on Oct 19, 2022

  1. Merge pull request #103 from auth0/SRE-57-Upload-opslevel-yaml

    OpsLevel repo catalog - upload opslevel.yml
    esarafianou authored Oct 19, 2022
    Copy the full SHA
    a197658 View commit details

Commits on Oct 21, 2022

  1. Copy the full SHA
    a17d843 View commit details

Commits on Oct 22, 2022

  1. release v3.0.1 (#106)

    support decryption for Okta assertions
    gkwang authored Oct 22, 2022
    Copy the full SHA
    f983358 View commit details

Commits on Oct 31, 2022

  1. Copy the full SHA
    63b4000 View commit details
  2. Merge pull request #107 from LoneRifle/master

    Bump @xmldom/xmldom to 0.8.5
    esarafianou authored Oct 31, 2022
    Copy the full SHA
    fe48761 View commit details

Commits on Nov 2, 2022

  1. release v3.0.2

    esarafianou committed Nov 2, 2022
    Copy the full SHA
    62cf884 View commit details
  2. Merge pull request #108 from auth0/v3.0.2

    release v3.0.2
    esarafianou authored Nov 2, 2022
    Copy the full SHA
    89fa6e9 View commit details

Commits on Nov 3, 2023

  1. Copy the full SHA
    bc6726f View commit details
  2. Merge pull request #111 from auth0/semgrep-update

    Update semgrep action to newer version
    es-sec authored Nov 3, 2023
    Copy the full SHA
    17d5036 View commit details

Commits on Jul 23, 2024

  1. Copy the full SHA
    f1a8e0e View commit details

Commits on Aug 5, 2024

  1. add test to github workflow (#113)

    * add test to github workflow
    
    * Add readme, drop node 18 support
    gkwang authored Aug 5, 2024
    Copy the full SHA
    a08c621 View commit details

Commits on Jan 15, 2025

  1. Add support for oaepHash=sha256

    panga committed Jan 15, 2025
    Copy the full SHA
    36e6993 View commit details

Commits on Jan 16, 2025

  1. Removed unused dependency

    panga committed Jan 16, 2025
    Copy the full SHA
    52712d6 View commit details

Commits on Jan 21, 2025

  1. Merge pull request #115 from panga/oaep

    Add support for sha256/512 encryption key OAEP digest methods
    madhuriravindramohan-okta authored Jan 21, 2025
    Copy the full SHA
    d02969f View commit details
Showing with 1,825 additions and 112 deletions.
  1. +20 −0 .github/workflows/semgrep.yml
  2. +45 −0 .github/workflows/test.yml
  3. +0 −1 CODEOWNERS
  4. +3 −2 README.md
  5. +2 −2 lib/templates/keyinfo.tpl.xml.js
  6. +38 −15 lib/xmlenc.js
  7. +6 −0 opslevel.yml
  8. +1,549 −78 package-lock.json
  9. +7 −9 package.json
  10. +96 −0 test/test-okta-enc-response.xml
  11. +28 −0 test/test-okta.pem
  12. +18 −4 test/xmlenc.encryptedkey.js
  13. +13 −1 test/xmlenc.integration.js
20 changes: 20 additions & 0 deletions .github/workflows/semgrep.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Semgrep

on:
pull_request_target: {}
push:
branches: ["master", "main"]
permissions:
contents: read
jobs:
semgrep:
name: Scan
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep
if: (github.actor != 'dependabot[bot]' && github.actor != 'snyk-bot')
steps:
- uses: actions/checkout@v3
- run: semgrep ci
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
45 changes: 45 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Build and Test

on:
merge_group:
workflow_dispatch:
pull_request:
types:
- opened
- synchronize
push:
branches:
- master

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node: [ 12, 14, 16 ]
name: Node ${{ matrix.node }} Test
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.ref }}

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run Mocha unit tests
run: npm run test

1 change: 0 additions & 1 deletion CODEOWNERS

This file was deleted.

5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[![Build Status](https://travis-ci.org/auth0/node-xml-encryption.png)](https://travis-ci.org/auth0/node-xml-encryption)

W3C XML Encryption implementation for node.js (http://www.w3.org/TR/xmlenc-core/)
W3C XML Encryption implementation for Node.js (http://www.w3.org/TR/xmlenc-core/)

Supports node >= 8
Node 18+ does not support Triple DES algorithms due to https://github.com/nodejs/node/issues/52017

## Usage

@@ -18,6 +18,7 @@ var options = {
pem: fs.readFileSync(__dirname + '/your_public_cert.pem'),
encryptionAlgorithm: 'http://www.w3.org/2001/04/xmlenc#aes256-cbc',
keyEncryptionAlgorithm: 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p',
keyEncryptionDigest: 'sha1',
disallowEncryptionWithInsecureAlgorithm: true,
warnInsecureAlgorithm: true
};
4 changes: 2 additions & 2 deletions lib/templates/keyinfo.tpl.xml.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
var escapehtml = require('escape-html');

module.exports = ({ encryptionPublicCert, encryptedKey, keyEncryptionMethod }) => `
module.exports = ({ encryptionPublicCert, encryptedKey, keyEncryptionMethod, keyEncryptionDigest }) => `
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="${escapehtml(keyEncryptionMethod)}">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#${escapehtml(keyEncryptionDigest)}" />
</e:EncryptionMethod>
<KeyInfo>
${encryptionPublicCert}
53 changes: 38 additions & 15 deletions lib/xmlenc.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
var crypto = require('crypto');
var xmldom = require('xmldom');
var xmldom = require('@xmldom/xmldom');
var xpath = require('xpath');
var utils = require('./utils');
var pki = require('node-forge').pki;

const insecureAlgorithms = [
//https://www.w3.org/TR/xmlenc-core1/#rsav15note
'http://www.w3.org/2001/04/xmlenc#rsa-1_5',
//https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA
'http://www.w3.org/2001/04/xmlenc#tripledes-cbc'];
function encryptKeyInfoWithScheme(symmetricKey, options, scheme, callback) {

function encryptKeyInfoWithScheme(symmetricKey, options, padding, callback) {
const symmetricKeyBuffer = Buffer.isBuffer(symmetricKey) ? symmetricKey : Buffer.from(symmetricKey, 'utf-8');

try {
var rsa_pub = pki.publicKeyFromPem(options.rsa_pub);
var encrypted = rsa_pub.encrypt(symmetricKey.toString('binary'), scheme);
var base64EncodedEncryptedKey = Buffer.from(encrypted, 'binary').toString('base64');
var encrypted = crypto.publicEncrypt({
key: options.rsa_pub,
oaepHash: padding == crypto.constants.RSA_PKCS1_OAEP_PADDING ? options.keyEncryptionDigest : undefined,
padding: padding
}, symmetricKeyBuffer);
var base64EncodedEncryptedKey = encrypted.toString('base64');

var params = {
encryptedKey: base64EncodedEncryptedKey,
encryptionPublicCert: '<X509Data><X509Certificate>' + utils.pemToCert(options.pem.toString()) + '</X509Certificate></X509Data>',
keyEncryptionMethod: options.keyEncryptionAlgorithm
keyEncryptionMethod: options.keyEncryptionAlgorithm,
keyEncryptionDigest: options.keyEncryptionDigest,
};

var result = utils.renderTemplate('keyinfo', params);
@@ -42,13 +48,14 @@ function encryptKeyInfo(symmetricKey, options, callback) {
&& insecureAlgorithms.indexOf(options.keyEncryptionAlgorithm) >= 0) {
return callback(new Error('encryption algorithm ' + options.keyEncryptionAlgorithm + 'is not secure'));
}
options.keyEncryptionDigest = options.keyEncryptionDigest || 'sha1';
switch (options.keyEncryptionAlgorithm) {
case 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p':
return encryptKeyInfoWithScheme(symmetricKey, options, 'RSA-OAEP', callback);
return encryptKeyInfoWithScheme(symmetricKey, options, crypto.constants.RSA_PKCS1_OAEP_PADDING, callback);

case 'http://www.w3.org/2001/04/xmlenc#rsa-1_5':
utils.warnInsecureAlgorithm(options.keyEncryptionAlgorithm, options.warnInsecureAlgorithm);
return encryptKeyInfoWithScheme(symmetricKey, options, 'RSAES-PKCS1-V1_5', callback);
return encryptKeyInfoWithScheme(symmetricKey, options, crypto.constants.RSA_PKCS1_PADDING, callback);

default:
return callback(new Error('encryption key algorithm not supported'));
@@ -215,6 +222,9 @@ function decryptKeyInfo(doc, options) {

var keyRetrievalMethodUri;
var keyInfo = xpath.select("//*[local-name(.)='KeyInfo' and namespace-uri(.)='http://www.w3.org/2000/09/xmldsig#']", doc)[0];
if (!keyInfo) {
keyInfo = xpath.select("//*[local-name(.)='EncryptedData']/*[local-name(.)='KeyInfo']", doc)[0];
}
var keyEncryptionMethod = xpath.select("//*[local-name(.)='KeyInfo']/*[local-name(.)='EncryptedKey']/*[local-name(.)='EncryptionMethod']", doc)[0];

if (!keyEncryptionMethod) { // try with EncryptedData->KeyInfo->RetrievalMethod
@@ -227,6 +237,20 @@ function decryptKeyInfo(doc, options) {
throw new Error('cant find encryption algorithm');
}

let oaepHash = 'sha1';
const keyDigestMethod = xpath.select("//*[local-name(.)='KeyInfo']/*[local-name(.)='EncryptedKey']/*[local-name(.)='EncryptionMethod']/*[local-name(.)='DigestMethod']", doc)[0];
if (keyDigestMethod) {
const keyDigestMethodAlgorithm = keyDigestMethod.getAttribute('Algorithm');
switch (keyDigestMethodAlgorithm) {
case 'http://www.w3.org/2000/09/xmldsig#sha256':
oaepHash = 'sha256';
break;
case 'http://www.w3.org/2000/09/xmldsig#sha512':
oaepHash = 'sha512';
break;
}
}

var keyEncryptionAlgorithm = keyEncryptionMethod.getAttribute('Algorithm');
if (options.disallowDecryptionWithInsecureAlgorithm
&& insecureAlgorithms.indexOf(keyEncryptionAlgorithm) >= 0) {
@@ -238,19 +262,18 @@ function decryptKeyInfo(doc, options) {

switch (keyEncryptionAlgorithm) {
case 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p':
return decryptKeyInfoWithScheme(encryptedKey, options, 'RSA-OAEP');
return decryptKeyInfoWithScheme(encryptedKey, options, crypto.constants.RSA_PKCS1_OAEP_PADDING, oaepHash);
case 'http://www.w3.org/2001/04/xmlenc#rsa-1_5':
utils.warnInsecureAlgorithm(keyEncryptionAlgorithm, options.warnInsecureAlgorithm);
return decryptKeyInfoWithScheme(encryptedKey, options, 'RSAES-PKCS1-V1_5');
return decryptKeyInfoWithScheme(encryptedKey, options, crypto.constants.RSA_PKCS1_PADDING);
default:
throw new Error('key encryption algorithm ' + keyEncryptionAlgorithm + ' not supported');
}
}

function decryptKeyInfoWithScheme(encryptedKey, options, scheme) {
var key = Buffer.from(encryptedKey.textContent, 'base64').toString('binary');
var private_key = pki.privateKeyFromPem(options.key);
var decrypted = private_key.decrypt(key, scheme);
function decryptKeyInfoWithScheme(encryptedKey, options, padding, oaepHash) {
const key = Buffer.from(encryptedKey.textContent, 'base64');
const decrypted = crypto.privateDecrypt({ key: options.key, padding, oaepHash}, key);
return Buffer.from(decrypted, 'binary');
}

6 changes: 6 additions & 0 deletions opslevel.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
version: 1
repository:
owner: iam_protocols
tier:
tags:
Loading