Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
do_get_profile(); // must be called before getting nsIX509CertDB
const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(
Ci.nsIX509CertDB
);
// If resolved, asyncVerifyPKCS7Object(pkcs7, data, signatureType) will return an array consisting
// of 3 elements for each SignerInfo of the PKCS7 message:
// - signatureResult - which describes the result of verifying the hash of data against the signature
// stored in pkcs7
// - certificateResult - which describes the result of certificate verification
// If the signature verification has failed, certificate verification is not run.
// - signerCertificate - which returns the signerCertificate from the pkcs7 message
// signerCertificate is null if the signature verification has failed (not equal to NS_OK).
// Empty PKCS7 message should return resolved promise with NS_ERROR_CMS_VERIFY_ERROR_PROCESSING
add_task(async function () {
info("Running PDF verification service test with empty input");
let pkcs7 = new Uint8Array();
let data = [new Uint8Array(0x10)];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
equal(result.length, 1);
let firstSignatureResult = result[0];
equal(
firstSignatureResult.signatureResult,
Cr.NS_ERROR_CMS_VERIFY_ERROR_PROCESSING
);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_ERROR_PROCESSING
);
equal(firstSignatureResult.signerCertificate, null);
});
// Empty data message should return resolved promise with NS_ERROR_CMS_VERIFY_ERROR_PROCESSING
add_task(async function () {
info("Running PDF verification service test with empty input");
let pkcs7 = new Uint8Array(0x10);
let data = [new Uint8Array()];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
equal(result.length, 1);
let firstSignatureResult = result[0];
equal(
firstSignatureResult.signatureResult,
Cr.NS_ERROR_CMS_VERIFY_ERROR_PROCESSING
);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_ERROR_PROCESSING
);
equal(firstSignatureResult.signerCertificate, null);
});
// ADBE_PKCS7_SHA1 is not supported
add_task(async function () {
info("Running PDF verification service test with unsupported signature type");
let pkcs7 = new Uint8Array(0x10);
let data = [new Uint8Array(0x10)];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_SHA1;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
equal(result.length, 1);
let firstSignatureResult = result[0];
equal(
firstSignatureResult.signatureResult,
Cr.NS_ERROR_CMS_VERIFY_ERROR_PROCESSING
);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_ERROR_PROCESSING
);
equal(firstSignatureResult.signerCertificate, null);
});
function pkcs7FromFile(certName) {
let certFile = do_get_file(`test_pdf_verification/${certName}.p7s`, false);
let certBytes = readFile(certFile);
let certBytesClean = certBytes
.replace("-----BEGIN PKCS7-----", "")
.replace("-----END PKCS7-----", "")
.replace(/\n/g, "");
const binary = atob(certBytesClean);
const len = binary.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
bytes[i] = binary.charCodeAt(i);
}
return bytes;
}
function readBinFromFile(dataName) {
let dataFile = do_get_file(`test_pdf_verification/${dataName}.bin`, false);
let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
Ci.nsIFileInputStream
);
fstream.init(dataFile, -1, 0, 0);
let available = fstream.available();
let data = available > 0 ? NetUtil.readInputStream(fstream, available) : "";
fstream.close();
return new Uint8Array(data);
}
// PKCS7 CMS message with the correct signature should return resolve promise
// with signatureResult to be equal to NS_OK
// and the signerCertificate being not null.
// Currently, certificate verification is not supported.
add_task(async function () {
info("Running PDF verification service test with a correct signature");
let pkcs7 = pkcs7FromFile("cert_correct");
let data = [readBinFromFile("data_correct")];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
let firstSignatureResult = result[0];
equal(result.length, 1);
equal(firstSignatureResult.signatureResult, Cr.NS_OK);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
ok(
firstSignatureResult.signerCertificate,
"Signer certificate should not be null/undefined"
);
});
// PKCS7 CMS message with the correct signature should return resolve promise
// with signatureResult to be equal to NS_OK
// and the signerCertificate being not null.
// Currently, certificate verification is not supported.
add_task(async function () {
info("Running PDF verification service test with a correct signature");
let pkcs7 = pkcs7FromFile("certificate_two_data_inputs");
// each dataPortion here is an Uint8Array
let dataPortion = readBinFromFile("data_correct");
let data = [dataPortion, dataPortion];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
equal(result.length, 1);
let firstSignatureResult = result[0];
equal(firstSignatureResult.signatureResult, Cr.NS_OK);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
ok(
firstSignatureResult.signerCertificate,
"Signer certificate should not be null/undefined"
);
});
// PKCS7 CMS message contains one SignerInfo with an incorrect signature.
add_task(async function () {
info("Running PDF verification service test with a incorrect signature");
let pkcs7 = pkcs7FromFile("cert_with_incorrect_signature");
let data = [readBinFromFile("data_correct")];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
equal(result.length, 1);
let firstSignatureResult = result[0];
equal(
firstSignatureResult.signatureResult,
getXPCOMStatusFromNSS(SEC_ERROR_PKCS7_BAD_SIGNATURE)
);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
equal(firstSignatureResult.signerCertificate, null);
});
// MD5 signatures are not supported.
add_task(async function () {
info("Running PDF verification service test with a md5 signature");
let pkcs7 = pkcs7FromFile("md5_signer_info");
let data = [readBinFromFile("data_correct")];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
equal(result.length, 1);
let firstSignatureResult = result[0];
equal(
firstSignatureResult.signatureResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_SIGNED
);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
equal(firstSignatureResult.signerCertificate, null);
});
// PKCS7 CMS message has 2 SignerInfo, both have correct signature (sha1/sha2)
add_task(async function () {
info(
"Running PDF verification service test with the CMS message containing two different SignerInfo, both have correct signatures"
);
let pkcs7 = pkcs7FromFile("two_correct_signatures");
let data = [readBinFromFile("data_correct")];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
// 2 SignerInfo results into 2 signature results
equal(result.length, 2);
let firstSignatureResult = result[0];
let secondSignatureResult = result[1];
equal(firstSignatureResult.signatureResult, Cr.NS_OK);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
ok(
firstSignatureResult.signerCertificate,
"Signer certificate should not be null/undefined"
);
equal(secondSignatureResult.signatureResult, Cr.NS_OK);
equal(
secondSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
ok(
secondSignatureResult.signerCertificate,
"Signer certificate should not be null/undefined"
);
});
// PKCS7 CMS message has 2 SignerInfo, one SignerInfo has a wrong digest
// We consider that the signature is verified iff all the SignerInfo contain the correct signature.
add_task(async function () {
info(
"Running PDF verification service test with the CMS message containing two different SignerInfo, only one has a correct signature"
);
let pkcs7 = pkcs7FromFile("one_correct_one_incorrect_hash");
let data = [readBinFromFile("data_correct")];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
equal(result.length, 2);
let firstSignatureResult = result[0];
let secondSignatureResult = result[1];
equal(firstSignatureResult.signatureResult, Cr.NS_OK);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
ok(
firstSignatureResult.signerCertificate,
"Signer certificate should not be null/undefined"
);
equal(
secondSignatureResult.signatureResult,
getXPCOMStatusFromNSS(SEC_ERROR_PKCS7_BAD_SIGNATURE)
);
equal(
secondSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
equal(secondSignatureResult.signerCertificate, null);
});
// PKCS7 CMS message has 2 SignerInfo, one SignerInfo has a correct digest, but an incorrect signature
add_task(async function () {
info(
"Running PDF verification service test with the CMS message containing two different SignerInfo, only one has a correct signature"
);
let pkcs7 = pkcs7FromFile("one_correct_one_incorrect_signature");
let data = [readBinFromFile("data_correct")];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
let firstSignatureResult = result[0];
let secondSignatureResult = result[1];
equal(firstSignatureResult.signatureResult, Cr.NS_OK);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
ok(
firstSignatureResult.signerCertificate,
"Signer certificate should not be null/undefined"
);
equal(
secondSignatureResult.signatureResult,
getXPCOMStatusFromNSS(SEC_ERROR_PKCS7_BAD_SIGNATURE)
);
equal(
secondSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
equal(secondSignatureResult.signerCertificate, null);
});
// PKCS7 CMS message with no SignerInfo
add_task(async function () {
info("Running PDF verification service test with no SignerInfo");
let pkcs7 = pkcs7FromFile("no_signer_info");
let data = [readBinFromFile("data_correct")];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
equal(result.length, 1);
let firstSignatureResult = result[0];
equal(
firstSignatureResult.signatureResult,
Cr.NS_ERROR_CMS_VERIFY_ERROR_PROCESSING
);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_ERROR_PROCESSING
);
equal(firstSignatureResult.signerCertificate, null);
});
// PKCS7 CMS message with no certificates
add_task(async function () {
info("Running PDF verification service test with an empty certificate list");
let pkcs7 = pkcs7FromFile("no_certificate");
let data = [readBinFromFile("data_correct")];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
equal(result.length, 1);
let firstSignatureResult = result[0];
equal(firstSignatureResult.signatureResult, Cr.NS_ERROR_CMS_VERIFY_NOCERT);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
equal(firstSignatureResult.signerCertificate, null);
});
// Test vector used in Poppler to test their implementation
// SignerCertificate subject name is "CN=RSA2048 test key for pdfsig"
add_task(async function () {
info("Running PDF verification service test with the Poppler TV");
let pkcs7 = pkcs7FromFile("poppler_signature");
let data = [readBinFromFile("poppler_data")];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
equal(result.length, 1);
let firstSignatureResult = result[0];
equal(firstSignatureResult.signatureResult, Cr.NS_OK);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
ok(
firstSignatureResult.signerCertificate,
"Signer certificate should not be null/undefined"
);
info(
"Certificate Subject Name: " +
firstSignatureResult.signerCertificate.subjectName
);
Assert.equal(
firstSignatureResult.signerCertificate.subjectName,
"CN=RSA2048 test key for pdfsig"
);
});
// Checking some of the properties of the returned certificate
// The certificate was generated to have the Issuer "Test" and the subjectName "Test"
add_task(async function () {
info("Running PDF verification service test with a correct signature");
let pkcs7 = pkcs7FromFile("cert_correct");
let data = [readBinFromFile("data_correct")];
let signatureType = Ci.nsIX509CertDB.ADBE_PKCS7_DETACHED;
let result = await certdb.asyncVerifyPKCS7Object(pkcs7, data, signatureType);
equal(result.length, 1);
let firstSignatureResult = result[0];
equal(firstSignatureResult.signatureResult, Cr.NS_OK);
equal(
firstSignatureResult.certificateResult,
Cr.NS_ERROR_CMS_VERIFY_NOT_YET_ATTEMPTED
);
ok(
firstSignatureResult.signerCertificate,
"Signer certificate should not be null/undefined"
);
info(
"Certificate Subject Name: " +
firstSignatureResult.signerCertificate.subjectName
);
Assert.equal(firstSignatureResult.signerCertificate.subjectName, "CN=Test");
info(
"Certificate Issuer Name: " +
firstSignatureResult.signerCertificate.issuerName
);
Assert.equal(firstSignatureResult.signerCertificate.issuerName, "CN=Test");
});