Skip to content

Commit 4fce444

Browse files
committed
Make the pkcs1 format more accepting of cruft
We should be able to deal with any random cruft outside of the BEGIN and END boundaries.
1 parent a0dc3c6 commit 4fce444

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

src/formats/pkcs1.js

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,30 @@ var ber = require('asn1').Ber;
22
var _ = require('../utils')._;
33
var utils = require('../utils');
44

5+
const PRIVATE_OPENING_BOUNDARY = '-----BEGIN RSA PRIVATE KEY-----';
6+
const PRIVATE_CLOSING_BOUNDARY = '-----END RSA PRIVATE KEY-----';
7+
8+
const PUBLIC_OPENING_BOUNDARY = '-----BEGIN RSA PUBLIC KEY-----';
9+
const PUBLIC_CLOSING_BOUNDARY = '-----END RSA PUBLIC KEY-----';
10+
11+
/**
12+
* Strips everything around the opening and closing lines, including the lines
13+
* themselves.
14+
*/
15+
function trimSurroundingText(data, opening, closing) {
16+
let openingBoundaryIndex = data.indexOf(opening);
17+
if (openingBoundaryIndex < 0) {
18+
throw Error('Unsupported key format - Missing BEGIN line');
19+
}
20+
21+
let closingBoundaryIndex = data.indexOf(closing, openingBoundaryIndex);
22+
if (closingBoundaryIndex < 0) {
23+
throw Error('Unsupported key format - Missing END line');
24+
}
25+
26+
return data.substring(openingBoundaryIndex + opening.length, closingBoundaryIndex);
27+
}
28+
529
module.exports = {
630
privateExport: function (key, options) {
731
options = options || {};
@@ -46,8 +70,7 @@ module.exports = {
4670
}
4771

4872
if (_.isString(data)) {
49-
var pem = data.replace('-----BEGIN RSA PRIVATE KEY-----', '')
50-
.replace('-----END RSA PRIVATE KEY-----', '')
73+
let pem = trimSurroundingText(data, PRIVATE_OPENING_BOUNDARY, PRIVATE_CLOSING_BOUNDARY)
5174
.replace(/\s+|\n\r|\n|\r$/gm, '');
5275
buffer = Buffer.from(pem, 'base64');
5376
} else {
@@ -103,8 +126,7 @@ module.exports = {
103126
}
104127

105128
if (_.isString(data)) {
106-
var pem = data.replace('-----BEGIN RSA PUBLIC KEY-----', '')
107-
.replace('-----END RSA PUBLIC KEY-----', '')
129+
var pem = trimSurroundingText(data, PUBLIC_OPENING_BOUNDARY, PUBLIC_CLOSING_BOUNDARY)
108130
.replace(/\s+|\n\r|\n|\r$/gm, '');
109131
buffer = Buffer.from(pem, 'base64');
110132
}
@@ -128,12 +150,13 @@ module.exports = {
128150
* @param data
129151
*/
130152
autoImport: function (key, data) {
131-
if (/^\s*-----BEGIN RSA PRIVATE KEY-----\s*(?=(([A-Za-z0-9+/=]+\s*)+))\1-----END RSA PRIVATE KEY-----\s*$/g.test(data)) {
153+
// [\S\s]* matches zero or more of any character
154+
if (/^[\S\s]*-----BEGIN RSA PRIVATE KEY-----\s*(?=(([A-Za-z0-9+/=]+\s*)+))\1-----END RSA PRIVATE KEY-----[\S\s]*$/g.test(data)) {
132155
module.exports.privateImport(key, data);
133156
return true;
134157
}
135158

136-
if (/^\s*-----BEGIN RSA PUBLIC KEY-----\s*(?=(([A-Za-z0-9+/=]+\s*)+))\1-----END RSA PUBLIC KEY-----\s*$/g.test(data)) {
159+
if (/^[\S\s]*-----BEGIN RSA PUBLIC KEY-----\s*(?=(([A-Za-z0-9+/=]+\s*)+))\1-----END RSA PUBLIC KEY-----[\S\s]*$/g.test(data)) {
137160
module.exports.publicImport(key, data);
138161
return true;
139162
}

test/tests.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,21 @@ describe('NodeRSA', function () {
336336
assert.equal(key.exportKey(), fileKeyPKCS1);
337337
});
338338

339+
it('should gracefully handle data outside of encapsulation boundaries for private keys', function () {
340+
let privateFileWithNoise = 'Lorem ipsum' + fs.readFileSync(keysFolder + 'private_pkcs1.pem') + 'dulce et decorum';
341+
let key = new NodeRSA(privateFileWithNoise);
342+
assert.equal(key.exportKey(), fileKeyPKCS1);
343+
});
344+
345+
it('should gracefully handle data outside of encapsulation boundaries for public keys', function () {
346+
let publicFileWithNoise = 'Lorem ipsum' + fs.readFileSync(keysFolder + 'public_pkcs1.pem') + 'dulce et decorum';
347+
let publicNodeRSA = new NodeRSA(publicFileWithNoise);
348+
assert.instanceOf(privateNodeRSA.keyPair, Object);
349+
assert(publicNodeRSA.isPublic());
350+
assert(publicNodeRSA.isPublic(true));
351+
assert(!publicNodeRSA.isPrivate());
352+
});
353+
339354
it('.importKey() from private components', function () {
340355
var key = new NodeRSA();
341356
key.importKey({

0 commit comments

Comments
 (0)