
There are dozens of links in the OpenPGP.js codebase that are http but could be replaced with https links. I've converted as many of them as i could find.
173 lines
6.1 KiB
JavaScript
173 lines
6.1 KiB
JavaScript
// GPG4Browsers - An OpenPGP implementation in javascript
|
|
// Copyright (C) 2011 Recurity Labs GmbH
|
|
//
|
|
// 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
|
|
|
|
/**
|
|
* PKCS1 encoding
|
|
* @requires crypto/crypto
|
|
* @requires crypto/hash
|
|
* @requires crypto/public_key/jsbn
|
|
* @requires crypto/random
|
|
* @requires util
|
|
* @module crypto/pkcs1
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
import random from './random.js';
|
|
import util from '../util.js';
|
|
import BigInteger from './public_key/jsbn.js';
|
|
import hash from './hash';
|
|
|
|
/**
|
|
* ASN1 object identifiers for hashes (See {@link https://tools.ietf.org/html/rfc4880#section-5.2.2})
|
|
*/
|
|
var hash_headers = [];
|
|
hash_headers[1] = [0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04,
|
|
0x10
|
|
];
|
|
hash_headers[2] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14];
|
|
hash_headers[3] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14];
|
|
hash_headers[8] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
|
|
0x04, 0x20
|
|
];
|
|
hash_headers[9] = [0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00,
|
|
0x04, 0x30
|
|
];
|
|
hash_headers[10] = [0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
|
|
0x00, 0x04, 0x40
|
|
];
|
|
hash_headers[11] = [0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05,
|
|
0x00, 0x04, 0x1C
|
|
];
|
|
|
|
/**
|
|
* Create padding with secure random data
|
|
* @private
|
|
* @param {Integer} length Length of the padding in bytes
|
|
* @return {String} Padding as string
|
|
*/
|
|
function getPkcs1Padding(length) {
|
|
var result = '';
|
|
var randomByte;
|
|
while (result.length < length) {
|
|
randomByte = random.getSecureRandomOctet();
|
|
if (randomByte !== 0) {
|
|
result += String.fromCharCode(randomByte);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
export default {
|
|
eme: {
|
|
/**
|
|
* create a EME-PKCS1-v1_5 padding (See {@link https://tools.ietf.org/html/rfc4880#section-13.1.1|RFC 4880 13.1.1})
|
|
* @param {String} M message to be encoded
|
|
* @param {Integer} k the length in octets of the key modulus
|
|
* @return {String} EME-PKCS1 padded message
|
|
*/
|
|
encode: function(M, k) {
|
|
var mLen = M.length;
|
|
// length checking
|
|
if (mLen > k - 11) {
|
|
throw new Error('Message too long');
|
|
}
|
|
// Generate an octet string PS of length k - mLen - 3 consisting of
|
|
// pseudo-randomly generated nonzero octets
|
|
var PS = getPkcs1Padding(k - mLen - 3);
|
|
// Concatenate PS, the message M, and other padding to form an
|
|
// encoded message EM of length k octets as EM = 0x00 || 0x02 || PS || 0x00 || M.
|
|
var EM = String.fromCharCode(0) +
|
|
String.fromCharCode(2) +
|
|
PS +
|
|
String.fromCharCode(0) +
|
|
M;
|
|
return EM;
|
|
},
|
|
/**
|
|
* decodes a EME-PKCS1-v1_5 padding (See {@link https://tools.ietf.org/html/rfc4880#section-13.1.2|RFC 4880 13.1.2})
|
|
* @param {String} EM encoded message, an octet string
|
|
* @return {String} message, an octet string
|
|
*/
|
|
decode: function(EM) {
|
|
// leading zeros truncated by jsbn
|
|
if (EM.charCodeAt(0) !== 0) {
|
|
EM = String.fromCharCode(0) + EM;
|
|
}
|
|
var firstOct = EM.charCodeAt(0);
|
|
var secondOct = EM.charCodeAt(1);
|
|
var i = 2;
|
|
while (EM.charCodeAt(i) !== 0 && i < EM.length) {
|
|
i++;
|
|
}
|
|
var psLen = i - 2;
|
|
var separator = EM.charCodeAt(i++);
|
|
if (firstOct === 0 && secondOct === 2 && psLen >= 8 && separator === 0) {
|
|
return EM.substr(i);
|
|
} else {
|
|
throw new Error('Decryption error');
|
|
}
|
|
}
|
|
},
|
|
|
|
emsa: {
|
|
/**
|
|
* create a EMSA-PKCS1-v1_5 padding (See {@link https://tools.ietf.org/html/rfc4880#section-13.1.3|RFC 4880 13.1.3})
|
|
* @param {Integer} algo Hash algorithm type used
|
|
* @param {String} M message to be encoded
|
|
* @param {Integer} emLen intended length in octets of the encoded message
|
|
* @returns {String} encoded message
|
|
*/
|
|
encode: function(algo, M, emLen) {
|
|
var i;
|
|
// Apply the hash function to the message M to produce a hash value H
|
|
var H = util.Uint8Array2str(hash.digest(algo, util.str2Uint8Array(M)));
|
|
if (H.length !== hash.getHashByteLength(algo)) {
|
|
throw new Error('Invalid hash length');
|
|
}
|
|
// produce an ASN.1 DER value for the hash function used.
|
|
// Let T be the full hash prefix
|
|
var T = '';
|
|
for (i = 0; i < hash_headers[algo].length; i++) {
|
|
T += String.fromCharCode(hash_headers[algo][i]);
|
|
}
|
|
// add hash value to prefix
|
|
T += H;
|
|
// and let tLen be the length in octets of T
|
|
var tLen = T.length;
|
|
if (emLen < tLen + 11) {
|
|
throw new Error('Intended encoded message length too short');
|
|
}
|
|
// an octet string PS consisting of emLen - tLen - 3 octets with hexadecimal value 0xFF
|
|
// The length of PS will be at least 8 octets
|
|
var PS = '';
|
|
for (i = 0; i < (emLen - tLen - 3); i++) {
|
|
PS += String.fromCharCode(0xff);
|
|
}
|
|
// Concatenate PS, the hash prefix T, and other padding to form the
|
|
// encoded message EM as EM = 0x00 || 0x01 || PS || 0x00 || T.
|
|
var EM = String.fromCharCode(0x00) +
|
|
String.fromCharCode(0x01) +
|
|
PS +
|
|
String.fromCharCode(0x00) +
|
|
T;
|
|
return new BigInteger(util.hexstrdump(EM), 16);
|
|
}
|
|
}
|
|
};
|