diff --git a/package.json b/package.json index 7a982c99dc..35bad999f1 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "dependencies": { "@types/jsonwebtoken": "^7.1.33", "faye-websocket": "0.9.3", - "jsonwebtoken": "7.1.9" + "jsonwebtoken": "7.1.9", + "node-forge": "0.7.1" }, "devDependencies": { "@types/chai": "^3.4.34", diff --git a/src/auth/credential.ts b/src/auth/credential.ts index 6c913e1aa4..e63c6454b6 100644 --- a/src/auth/credential.ts +++ b/src/auth/credential.ts @@ -15,6 +15,7 @@ */ import * as jwt from 'jsonwebtoken'; +import * as forge from 'node-forge'; // Use untyped import syntax for Node built-ins import fs = require('fs'); @@ -167,6 +168,14 @@ export class Certificate { if (typeof errorMessage !== 'undefined') { throw new FirebaseAppError(AppErrorCodes.INVALID_CREDENTIAL, errorMessage); } + + try { + forge.pki.privateKeyFromPem(this.privateKey); + } catch (error) { + throw new FirebaseAppError( + AppErrorCodes.INVALID_CREDENTIAL, + 'Failed to parse private key: ' + error); + } } } diff --git a/test/unit/auth/credential.spec.ts b/test/unit/auth/credential.spec.ts index 6f31bf5646..4892ae7546 100644 --- a/test/unit/auth/credential.spec.ts +++ b/test/unit/auth/credential.spec.ts @@ -171,7 +171,7 @@ describe('Credential', () => { }).to.throw('Certificate object must contain a string "client_email" property'); }); - it('should throw if certificate object does not contain a valid "private_key"', () => { + it('should throw if certificate object does not contain a "private_key"', () => { mockCertificateObject.private_key = ''; expect(() => { @@ -185,6 +185,14 @@ describe('Credential', () => { }).to.throw('Certificate object must contain a string "private_key" property'); }); + it('should throw if certificate object does not contain a valid "private_key"', () => { + mockCertificateObject.private_key = 'invalid.key'; + + expect(() => { + return new Certificate(mockCertificateObject); + }).to.throw('Failed to parse private key: Error: Invalid PEM formatted message.'); + }); + it('should not throw given a valid certificate object', () => { expect(() => { return new Certificate(mockCertificateObject);