From 54b79be0b0f4e14bdebf5a6b18f26baf2d386b52 Mon Sep 17 00:00:00 2001 From: Ismael Bejarano Date: Fri, 12 Aug 2016 00:23:44 -0300 Subject: [PATCH] Add and remove PKCS5 padding --- src/crypto/index.js | 3 +++ src/crypto/pkcs5.js | 62 ++++++++++++++++++++++++++++++++++++++++++++ test/crypto/index.js | 1 + test/crypto/pkcs5.js | 41 +++++++++++++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 src/crypto/pkcs5.js create mode 100644 test/crypto/pkcs5.js diff --git a/src/crypto/index.js b/src/crypto/index.js index d87a18ee..b82d8b7b 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -13,6 +13,7 @@ import publicKey from './public_key'; import signature from './signature'; import random from './random'; import pkcs1 from './pkcs1'; +import pkcs5 from './pkcs5.js'; import crypto from './crypto.js'; import rfc3394 from './rfc3394.js'; @@ -33,6 +34,8 @@ const mod = { random: random, /** @see module:crypto/pkcs1 */ pkcs1: pkcs1, + /** @see module:crypto/pkcs5 */ + pkcs5: pkcs5, /** @see module:crypto/rfc3394 */ rfc3394: rfc3394, }; diff --git a/src/crypto/pkcs5.js b/src/crypto/pkcs5.js new file mode 100644 index 00000000..fc1e694a --- /dev/null +++ b/src/crypto/pkcs5.js @@ -0,0 +1,62 @@ +// OpenPGP.js - An OpenPGP implementation in javascript +// Copyright (C) 2015-2016 Decentral +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3.0 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +// Functions to add and remove PKCS5 padding + +/** + * PKCS5 padding + * @module crypto/pkcs5 + */ + +function getPkcs5Padding(length) { + const c = 8 - (length % 8); + var result = []; + for (var i = 0; i < c; ++i) { + result.push(String.fromCharCode(c)); + } + return result.join(""); +} + +/** + * Add pkcs5 padding to a text. + * @param {String} msg Text to add padding + * @return {String} Text with padding added + */ +function addPadding(msg) { + return msg + getPkcs5Padding(msg.length); +} + +/** + * Remove pkcs5 padding from a string. + * @param {String} msg Text to remove padding from + * @return {String} Text with padding removed + */ +function removePadding(msg) { + var len = msg.length; + if (len > 0) { + var c = msg.charCodeAt(len - 1); + if (c >= 1 && c <= 8) { + return msg.substr(0, len - c); + } + } + throw new Error('Invalid padding'); +} + +module.exports = { + addPadding: addPadding, + removePadding: removePadding +}; diff --git a/test/crypto/index.js b/test/crypto/index.js index 56685ed9..7429aaba 100644 --- a/test/crypto/index.js +++ b/test/crypto/index.js @@ -3,5 +3,6 @@ describe('Crypto', function () { require('./hash'); require('./random.js'); require('./crypto.js'); + require('./pkcs5.js'); require('./rfc3394.js'); }); diff --git a/test/crypto/pkcs5.js b/test/crypto/pkcs5.js new file mode 100644 index 00000000..98b6a591 --- /dev/null +++ b/test/crypto/pkcs5.js @@ -0,0 +1,41 @@ +'use strict'; + +var openpgp = typeof window !== 'undefined' && window.openpgp ? window.openpgp : require('../../dist/openpgp'); + +var expect = require('chai').expect; + +describe('PKCS5 padding', function() { + function repeat(pattern, count) { + var result = ''; + for (var k=0; k 8, 8..15 -> 16 + var l = Math.ceil((s.length+1)/8)*8; + var c = l - s.length; + expect(r.length).to.equal(l); + expect(c).is.at.least(1).is.at.most(8); + expect(r.substr(-1)).to.equal(String.fromCharCode(c)); + s += ' '; + } + }); + it('Remove padding', function () { + for (var k=1; k<=8; ++k) { + var s = repeat(' ', 8-k); + var r = s + repeat(String.fromCharCode(k), k); + var t = pkcs5.removePadding(r); + expect(t).to.equal(s); + } + }); + it('Invalid padding', function () { + expect(function () {pkcs5.removePadding(' ');}).to.throw(Error, /Invalid padding/); + expect(function () {pkcs5.removePadding('');}).to.throw(Error, /Invalid padding/); + }); +});