зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1332636 - Remove PSM support for Firefox Marketplace apps and Trusted Hosted Apps. r=keeler
THA was removed in Bug 1196988. After Bug 1235869 and Bug 1238079, Firefox Marketplace apps are at most supported by B2G, and B2G only code doesn't need to be in m-c anymore. MozReview-Commit-ID: DAx5lRdYQo0 --HG-- extra : rebase_source : e7fc32195def3acda2d53a6e3cb969f1e8a9a9a1
This commit is contained in:
Родитель
3bc43f5bf1
Коммит
fa71c479fc
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "AppTrustDomain.h"
|
||||
|
||||
#include "MainThreadUtils.h"
|
||||
#include "certdb.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
|
@ -19,16 +20,8 @@
|
|||
#include "pkix/pkixnss.h"
|
||||
#include "prerror.h"
|
||||
|
||||
// Generated in Makefile.in
|
||||
#include "marketplace-prod-public.inc"
|
||||
#include "marketplace-prod-reviewers.inc"
|
||||
#include "marketplace-dev-public.inc"
|
||||
#include "marketplace-dev-reviewers.inc"
|
||||
#include "marketplace-stage.inc"
|
||||
// Generated by gen_cert_header.py, which gets called by the build system.
|
||||
#include "xpcshell.inc"
|
||||
// Trusted Hosted Apps Certificates
|
||||
#include "manifest-signing-root.inc"
|
||||
#include "manifest-signing-test-root.inc"
|
||||
// Add-on signing Certificates
|
||||
#include "addons-public.inc"
|
||||
#include "addons-stage.inc"
|
||||
|
@ -39,7 +32,6 @@ using namespace mozilla::pkix;
|
|||
|
||||
extern mozilla::LazyLogModule gPIPNSSLog;
|
||||
|
||||
static const unsigned int DEFAULT_MIN_RSA_BITS = 2048;
|
||||
static char kDevImportedDER[] =
|
||||
"network.http.signed-packages.developer-root";
|
||||
|
||||
|
@ -52,7 +44,6 @@ unsigned int AppTrustDomain::sDevImportedDERLen = 0;
|
|||
AppTrustDomain::AppTrustDomain(UniqueCERTCertList& certChain, void* pinArg)
|
||||
: mCertChain(certChain)
|
||||
, mPinArg(pinArg)
|
||||
, mMinRSABits(DEFAULT_MIN_RSA_BITS)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -66,33 +57,6 @@ AppTrustDomain::SetTrustedRoot(AppTrustedRoot trustedRoot)
|
|||
|
||||
switch (trustedRoot)
|
||||
{
|
||||
case nsIX509CertDB::AppMarketplaceProdPublicRoot:
|
||||
trustedDER.data = const_cast<uint8_t*>(marketplaceProdPublicRoot);
|
||||
trustedDER.len = mozilla::ArrayLength(marketplaceProdPublicRoot);
|
||||
break;
|
||||
|
||||
case nsIX509CertDB::AppMarketplaceProdReviewersRoot:
|
||||
trustedDER.data = const_cast<uint8_t*>(marketplaceProdReviewersRoot);
|
||||
trustedDER.len = mozilla::ArrayLength(marketplaceProdReviewersRoot);
|
||||
break;
|
||||
|
||||
case nsIX509CertDB::AppMarketplaceDevPublicRoot:
|
||||
trustedDER.data = const_cast<uint8_t*>(marketplaceDevPublicRoot);
|
||||
trustedDER.len = mozilla::ArrayLength(marketplaceDevPublicRoot);
|
||||
break;
|
||||
|
||||
case nsIX509CertDB::AppMarketplaceDevReviewersRoot:
|
||||
trustedDER.data = const_cast<uint8_t*>(marketplaceDevReviewersRoot);
|
||||
trustedDER.len = mozilla::ArrayLength(marketplaceDevReviewersRoot);
|
||||
break;
|
||||
|
||||
case nsIX509CertDB::AppMarketplaceStageRoot:
|
||||
trustedDER.data = const_cast<uint8_t*>(marketplaceStageRoot);
|
||||
trustedDER.len = mozilla::ArrayLength(marketplaceStageRoot);
|
||||
// The staging root was generated with a 1024-bit key.
|
||||
mMinRSABits = 1024u;
|
||||
break;
|
||||
|
||||
case nsIX509CertDB::AppXPCShellRoot:
|
||||
trustedDER.data = const_cast<uint8_t*>(xpcshellRoot);
|
||||
trustedDER.len = mozilla::ArrayLength(xpcshellRoot);
|
||||
|
@ -318,7 +282,7 @@ Result
|
|||
AppTrustDomain::CheckRSAPublicKeyModulusSizeInBits(
|
||||
EndEntityOrCA /*endEntityOrCA*/, unsigned int modulusSizeInBits)
|
||||
{
|
||||
if (modulusSizeInBits < mMinRSABits) {
|
||||
if (modulusSizeInBits < 2048u) {
|
||||
return Result::ERROR_INADEQUATE_KEY_SIZE;
|
||||
}
|
||||
return Success;
|
||||
|
|
|
@ -76,7 +76,6 @@ private:
|
|||
/*out*/ UniqueCERTCertList& mCertChain;
|
||||
void* mPinArg; // non-owning!
|
||||
UniqueCERTCertificate mTrustedRoot;
|
||||
unsigned int mMinRSABits;
|
||||
|
||||
static StaticMutex sMutex;
|
||||
static UniquePtr<unsigned char[]> sDevImportedDERData;
|
||||
|
|
|
@ -27,13 +27,6 @@ def _create_header(array_name, cert_bytes):
|
|||
# def arrayName(header, cert_filename):
|
||||
# header.write(_create_header("arrayName", cert_filename))
|
||||
array_names = [
|
||||
'marketplaceProdPublicRoot',
|
||||
'marketplaceProdReviewersRoot',
|
||||
'marketplaceDevPublicRoot',
|
||||
'marketplaceDevReviewersRoot',
|
||||
'marketplaceStageRoot',
|
||||
'trustedAppPublicRoot',
|
||||
'trustedAppTestRoot',
|
||||
'xpcshellRoot',
|
||||
'addonsPublicRoot',
|
||||
'addonsStageRoot',
|
||||
|
|
Двоичные данные
security/apps/marketplace-dev-public.crt
Двоичные данные
security/apps/marketplace-dev-public.crt
Двоичный файл не отображается.
Двоичные данные
security/apps/marketplace-dev-reviewers.crt
Двоичные данные
security/apps/marketplace-dev-reviewers.crt
Двоичный файл не отображается.
Двоичные данные
security/apps/marketplace-prod-public.crt
Двоичные данные
security/apps/marketplace-prod-public.crt
Двоичный файл не отображается.
Двоичные данные
security/apps/marketplace-prod-reviewers.crt
Двоичные данные
security/apps/marketplace-prod-reviewers.crt
Двоичный файл не отображается.
Двоичные данные
security/apps/marketplace-stage.crt
Двоичные данные
security/apps/marketplace-stage.crt
Двоичный файл не отображается.
|
@ -24,13 +24,6 @@ for var in ('DLL_PREFIX', 'DLL_SUFFIX'):
|
|||
test_ssl_path = '/security/manager/ssl/tests/unit'
|
||||
|
||||
headers_arrays_certs = [
|
||||
('marketplace-prod-public.inc', 'marketplaceProdPublicRoot', 'marketplace-prod-public.crt'),
|
||||
('marketplace-prod-reviewers.inc', 'marketplaceProdReviewersRoot', 'marketplace-prod-reviewers.crt'),
|
||||
('marketplace-dev-public.inc', 'marketplaceDevPublicRoot', 'marketplace-dev-public.crt'),
|
||||
('marketplace-dev-reviewers.inc', 'marketplaceDevReviewersRoot', 'marketplace-dev-reviewers.crt'),
|
||||
('marketplace-stage.inc', 'marketplaceStageRoot', 'marketplace-stage.crt'),
|
||||
('manifest-signing-root.inc', 'trustedAppPublicRoot', 'trusted-app-public.der'),
|
||||
('manifest-signing-test-root.inc', 'trustedAppTestRoot', test_ssl_path + '/test_signed_manifest/trusted_ca1.der'),
|
||||
('xpcshell.inc', 'xpcshellRoot', test_ssl_path + '/test_signed_apps/trusted_ca1.der'),
|
||||
('addons-public.inc', 'addonsPublicRoot', 'addons-public.crt'),
|
||||
('addons-stage.inc', 'addonsStageRoot', 'addons-stage.crt'),
|
||||
|
|
|
@ -241,11 +241,11 @@ interface nsIX509CertDB : nsISupports {
|
|||
* as input, to encourage users of the API to verify the signature as the
|
||||
* first step in opening the JAR.
|
||||
*/
|
||||
const AppTrustedRoot AppMarketplaceProdPublicRoot = 1;
|
||||
const AppTrustedRoot AppMarketplaceProdReviewersRoot = 2;
|
||||
const AppTrustedRoot AppMarketplaceDevPublicRoot = 3;
|
||||
const AppTrustedRoot AppMarketplaceDevReviewersRoot = 4;
|
||||
const AppTrustedRoot AppMarketplaceStageRoot = 5;
|
||||
// 1 used to be AppMarketplaceProdPublicRoot.
|
||||
// 2 used to be AppMarketplaceProdReviewersRoot.
|
||||
// 3 used to be AppMarketplaceDevPublicRoot.
|
||||
// 4 used to be AppMarketplaceDevReviewersRoot.
|
||||
// 5 used to be AppMarketplaceStageRoot.
|
||||
const AppTrustedRoot AppXPCShellRoot = 6;
|
||||
const AppTrustedRoot AddonsPublicRoot = 7;
|
||||
const AppTrustedRoot AddonsStageRoot = 8;
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
do_get_profile(); // must be called before getting nsIX509CertDB
|
||||
const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService(Ci.nsIX509CertDB);
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function check_open_result(name, expectedRv) {
|
||||
return function openSignedAppFileCallback(rv, aZipReader, aSignerCert) {
|
||||
do_print("openSignedAppFileCallback called for " + name);
|
||||
equal(rv, expectedRv, "Actual and expected return value should match");
|
||||
equal(aZipReader != null, Components.isSuccessCode(expectedRv),
|
||||
"ZIP reader should be null only if the return value denotes failure");
|
||||
equal(aSignerCert != null, Components.isSuccessCode(expectedRv),
|
||||
"Signer cert should be null only if the return value denotes failure");
|
||||
run_next_test();
|
||||
};
|
||||
}
|
||||
|
||||
function original_app_path(test_name) {
|
||||
return do_get_file("test_signed_apps/" + test_name + ".zip", false);
|
||||
}
|
||||
|
||||
// Test that we no longer trust the test root cert that was originally used
|
||||
// during development of B2G 1.0.
|
||||
add_test(function () {
|
||||
certdb.openSignedAppFileAsync(
|
||||
Ci.nsIX509CertDB.AppMarketplaceProdPublicRoot,
|
||||
original_app_path("test-privileged-app-test-1.0"),
|
||||
check_open_result("test-privileged-app-test-1.0",
|
||||
getXPCOMStatusFromNSS(SEC_ERROR_UNKNOWN_ISSUER)));
|
||||
});
|
||||
|
||||
// Test that we trust the root cert used by by the Firefox Marketplace.
|
||||
add_test(function () {
|
||||
certdb.openSignedAppFileAsync(
|
||||
Ci.nsIX509CertDB.AppMarketplaceProdPublicRoot,
|
||||
original_app_path("privileged-app-test-1.0"),
|
||||
check_open_result("privileged-app-test-1.0", Cr.NS_OK));
|
||||
});
|
|
@ -1,17 +0,0 @@
|
|||
This folder contains the scripts needed to generate signed manifest files
|
||||
to verify the Trusted Hosted Apps concept.
|
||||
|
||||
Prerequisites:
|
||||
|
||||
* NSS 3.4 or higher.
|
||||
* Python 2.7 (should work with 2.6 also)
|
||||
* Bash
|
||||
* OpenSSL
|
||||
|
||||
Usage:
|
||||
|
||||
Run
|
||||
I) For usage info execute ./create_test_files.sh --help
|
||||
|
||||
II) Upload the signed manifest.webapp and manifest.sig to the
|
||||
application hosting server.
|
|
@ -1,181 +0,0 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Mode: shell-script; sh-indentation: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/.
|
||||
|
||||
export BASE_PATH=`dirname $0`
|
||||
echo $BASE_PATH
|
||||
|
||||
# location of the 'sign_b2g_manifest.py' script
|
||||
export SIGN_SCR_PATH=.
|
||||
|
||||
DB_PATH=${BASE_PATH}/signingDB
|
||||
PASSWORD_FILE=${DB_PATH}/passwordfile
|
||||
VALID_MANIFEST_PATH=${BASE_PATH}/testValidSignedManifest
|
||||
INVALID_MANIFEST_PATH=${BASE_PATH}/testInvalidSignedManifest
|
||||
|
||||
TRUSTED_EE=trusted_ee1
|
||||
UNTRUSTED_EE=untrusted_ee1
|
||||
TRUSTED_CA=trusted_ca1
|
||||
UNTRUSTED_CA=untrusted_ca1
|
||||
|
||||
# Print usage info
|
||||
usage() {
|
||||
echo
|
||||
echo
|
||||
tput bold
|
||||
echo "NAME"
|
||||
tput sgr0
|
||||
echo " create_test_files.sh - Signing a manifest for Trusted Hosted Apps."
|
||||
echo
|
||||
tput bold
|
||||
echo "SYNOPSIS"
|
||||
tput sgr0
|
||||
echo " create_test_files.sh"
|
||||
echo " create_test_files.sh [--regenerate-test-certs]"
|
||||
echo " create_test_files.sh [--help]"
|
||||
echo
|
||||
tput bold
|
||||
echo "DESCRIPTION"
|
||||
tput sgr0
|
||||
echo " The script signs a manifest for Trusted Hosted Apps if no parameter"
|
||||
echo " is given and if the manifest file and a certificate database directory"
|
||||
echo " is present in the current directory."
|
||||
echo " Two directories ./testValidSignedManifest and ./testInvalidSignedManifest"
|
||||
echo " are generated containing a manifest signature file each, signed with valid"
|
||||
echo " and invalid certificates respectively."
|
||||
echo " If the --regenerate-test-certs parameter is given, a new certificate database"
|
||||
echo " directory is generated before the signing takes place."
|
||||
echo " If the certificate database is not present and the --regenerate-test-certs"
|
||||
echo " parameter is not given the script exits whithout any operations."
|
||||
echo
|
||||
tput bold
|
||||
echo "OPTIONS"
|
||||
echo " --regenerate-test-certs,"
|
||||
tput sgr0
|
||||
echo " Generates a test certificate database and then signs the manifest.webapp"
|
||||
echo " file in the current directory."
|
||||
echo
|
||||
tput bold
|
||||
echo " --help,"
|
||||
tput sgr0
|
||||
echo " Show this usage information."
|
||||
echo
|
||||
}
|
||||
|
||||
# Function to create a signing database
|
||||
# Parameters:
|
||||
# $1: Output directory (where the DB will be created)
|
||||
# $2: Password file
|
||||
createDB() {
|
||||
local db_path=${1}
|
||||
local password_file=${2}
|
||||
|
||||
mkdir -p ${db_path}
|
||||
echo insecurepassword > ${password_file}
|
||||
certutil -d ${db_path} -N -f ${password_file} 2>&1 >/dev/null
|
||||
}
|
||||
|
||||
# Add a CA cert and a signing cert to the database
|
||||
# Arguments:
|
||||
# $1: DB directory
|
||||
# $2: CA CN (don't include the CN=, just the value)
|
||||
# $3: Signing Cert CN (don't include the CN=, just the value)
|
||||
# $4: CA short name (don't use spaces!)
|
||||
# $5: Signing Cert short name (don't use spaces!)
|
||||
# $6: Password file
|
||||
addCerts() {
|
||||
local db_path=${1}
|
||||
local password_file=${6}
|
||||
|
||||
org="O=Example Trusted Corporation,L=Mountain View,ST=CA,C=US"
|
||||
ca_subj="CN=${2},${org}"
|
||||
ee_subj="CN=${3},${org}"
|
||||
|
||||
noisefile=/tmp/noise.$$
|
||||
head -c 32 /dev/urandom > ${noisefile}
|
||||
|
||||
ca_responses=/tmp/caresponses.$$
|
||||
ee_responses=/tmp/earesponses
|
||||
|
||||
echo y > ${ca_responses} # Is this a CA?
|
||||
echo >> ${ca_responses} # Accept default path length constraint (no constraint)
|
||||
echo y >> ${ca_responses} # Is this a critical constraint?
|
||||
echo n > ${ee_responses} # Is this a CA?
|
||||
echo >> ${ee_responses} # Accept default path length constraint (no constraint)
|
||||
echo y >> ${ee_responses} # Is this a critical constraint?
|
||||
|
||||
make_cert="certutil -d ${db_path} -f ${password_file} -S -g 2048 -Z SHA256 \
|
||||
-z ${noisefile} -y 3 -2 --extKeyUsage critical,codeSigning"
|
||||
${make_cert} -v 480 -n ${4} -m 1 -s "${ca_subj}" --keyUsage critical,certSigning \
|
||||
-t ",,CTu" -x < ${ca_responses} 2>&1 >/dev/null
|
||||
${make_cert} -v 240 -n ${5} -c ${4} -m 2 -s "${ee_subj}" --keyUsage critical,digitalSignature \
|
||||
-t ",,," < ${ee_responses} 2>&1 >/dev/null
|
||||
|
||||
certutil -d ${db_path} -L -n ${4} -r -o ${SIGN_SCR_PATH}/${4}.der
|
||||
|
||||
rm -f ${noisefile} ${ee_responses} ${ca_responses}
|
||||
}
|
||||
|
||||
# Signs a manifest
|
||||
# Parameters:
|
||||
# $1: Database directory
|
||||
# $2: Unsigned manifest file path
|
||||
# $3: Signed manifest file path
|
||||
# $4: Nickname of the signing certificate
|
||||
# $5: Password file
|
||||
signManifest() {
|
||||
local db_path=${1}
|
||||
local password_file=${5}
|
||||
|
||||
python ${BASE_PATH}/${SIGN_SCR_PATH}/sign_b2g_manifest.py -d ${db_path} \
|
||||
-f ${password_file} -k ${4} -i ${2} -o ${3}
|
||||
}
|
||||
|
||||
# Generate the necessary files to be used for the signing
|
||||
generate_files() {
|
||||
# First create a new couple of signing DBs
|
||||
rm -rf ${DB_PATH} ${VALID_MANIFEST_PATH} ${INVALID_MANIFEST_PATH}
|
||||
createDB ${DB_PATH} ${PASSWORD_FILE}
|
||||
addCerts ${DB_PATH} "Trusted Valid CA" "Trusted Corp Cert" ${TRUSTED_CA} ${TRUSTED_EE} ${PASSWORD_FILE}
|
||||
addCerts ${DB_PATH} "Trusted Invalid CA" "Trusted Invalid Cert" ${UNTRUSTED_CA} ${UNTRUSTED_EE} ${PASSWORD_FILE}
|
||||
}
|
||||
|
||||
#Start of execution
|
||||
if [ ${1} ] && [ "${1}" == '--regenerate-test-certs' ]; then
|
||||
generate_files
|
||||
elif [ "${1}" == '--help' ]; then
|
||||
usage
|
||||
exit 1
|
||||
else
|
||||
if [ -d ${DB_PATH} ]; then
|
||||
rm -rf ${VALID_MANIFEST_PATH} ${INVALID_MANIFEST_PATH}
|
||||
else
|
||||
echo "Error! The directory ${DB_PATH} does not exist!"
|
||||
echo "New certificate database must be created!"
|
||||
usage $0
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create all the test manifests
|
||||
mkdir -p ${VALID_MANIFEST_PATH}
|
||||
mkdir -p ${INVALID_MANIFEST_PATH}
|
||||
|
||||
CURDIR=`pwd`
|
||||
cd $CURDIR
|
||||
|
||||
# Sign a manifest file with a known issuer
|
||||
signManifest ${DB_PATH} ${BASE_PATH}/manifest.webapp \
|
||||
${VALID_MANIFEST_PATH}/manifest.sig \
|
||||
${TRUSTED_EE} ${PASSWORD_FILE}
|
||||
|
||||
# Sign a manifest file with a unknown issuer
|
||||
signManifest ${DB_PATH} ${BASE_PATH}/manifest.webapp \
|
||||
${INVALID_MANIFEST_PATH}/manifest.sig \
|
||||
${UNTRUSTED_EE} ${PASSWORD_FILE}
|
||||
|
||||
echo "Done!"
|
|
@ -1,10 +0,0 @@
|
|||
{ "name": "Trusted App Example",
|
||||
"description": "A Manifest for a Trusted Hosted Application",
|
||||
"type": "trusted",
|
||||
"launch_path": "/index.html",
|
||||
"icons": { "128" : "icon-128.png" },
|
||||
"version": 1,
|
||||
"csp" : "script-src https://www.example.com; style-src https://www.example.com",
|
||||
"permissions": { "device-storage:videos":{ "access": "readonly" }, "device-storage:pictures":{ "access": "readwrite" } },
|
||||
"default_locale": "en-US"
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python
|
||||
#
|
||||
# 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/.
|
||||
|
||||
# flake8: noqa
|
||||
|
||||
from ctypes import *
|
||||
import os
|
||||
import sys
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
libprefix = "lib"
|
||||
libsuffix = ".dylib"
|
||||
elif os.name == 'posix':
|
||||
libprefix = "lib"
|
||||
libsuffix = ".so"
|
||||
else: # assume windows
|
||||
libprefix = ""
|
||||
libsuffix = ".dll"
|
||||
|
||||
plc = cdll.LoadLibrary(libprefix + "plc4" + libsuffix)
|
||||
nspr = cdll.LoadLibrary(libprefix + "nspr4" + libsuffix)
|
||||
nss = cdll.LoadLibrary(libprefix + "nss3" + libsuffix)
|
||||
smime = cdll.LoadLibrary(libprefix + "smime3" + libsuffix)
|
||||
|
||||
nspr.PR_GetError.argtypes = []
|
||||
nspr.PR_GetError.restype = c_int32
|
||||
nspr.PR_ErrorToName.argtypes = [c_int32]
|
||||
nspr.PR_ErrorToName.restype = c_char_p
|
||||
|
||||
def raise_if_not_SECSuccess(rv):
|
||||
SECSuccess = 0
|
||||
if (rv != SECSuccess):
|
||||
raise ValueError(nspr.PR_ErrorToName(nspr.PR_GetError()))
|
||||
|
||||
def raise_if_NULL(p):
|
||||
if not p:
|
||||
raise ValueError(nspr.PR_ErrorToName(nspr.PR_GetError()))
|
||||
return p
|
||||
|
||||
PRBool = c_int
|
||||
SECStatus = c_int
|
||||
|
||||
# from secoidt.h
|
||||
SEC_OID_SHA1 = 4
|
||||
|
||||
# from certt.h
|
||||
certUsageObjectSigner = 6
|
||||
|
||||
class SECItem(Structure):
|
||||
_fields_ = [("type", c_int),
|
||||
("data", c_char_p),
|
||||
("len", c_uint)]
|
||||
|
||||
nss.NSS_Init.argtypes = [c_char_p]
|
||||
nss.NSS_Init.restype = SECStatus
|
||||
def NSS_Init(db_dir):
|
||||
nss.NSS_Init.argtypes = [c_char_p]
|
||||
nss.NSS_Init.restype = SECStatus
|
||||
raise_if_not_SECSuccess(nss.NSS_Init(db_dir))
|
||||
|
||||
nss.NSS_Shutdown.argtypes = []
|
||||
nss.NSS_Shutdown.restype = SECStatus
|
||||
def NSS_Shutdown():
|
||||
raise_if_not_SECSuccess(nss.NSS_Shutdown())
|
||||
|
||||
PK11PasswordFunc = CFUNCTYPE(c_char_p, c_void_p, PRBool, c_char_p)
|
||||
|
||||
# pass the result of this as the wincx parameter when a wincx is required
|
||||
nss.PK11_SetPasswordFunc.argtypes = [PK11PasswordFunc]
|
||||
nss.PK11_SetPasswordFunc.restype = None
|
||||
|
||||
# Set the return type as *void so Python doesn't touch it
|
||||
plc.PL_strdup.argtypes = [c_char_p]
|
||||
plc.PL_strdup.restype = c_void_p
|
||||
def SetPasswordContext(password):
|
||||
def callback(slot, retry, arg):
|
||||
return plc.PL_strdup(password)
|
||||
wincx = PK11PasswordFunc(callback)
|
||||
nss.PK11_SetPasswordFunc(wincx)
|
||||
return wincx
|
||||
|
||||
nss.CERT_GetDefaultCertDB.argtypes = []
|
||||
nss.CERT_GetDefaultCertDB.restype = c_void_p
|
||||
def CERT_GetDefaultCertDB():
|
||||
return raise_if_NULL(nss.CERT_GetDefaultCertDB())
|
||||
|
||||
nss.PK11_FindCertFromNickname.argtypes = [c_char_p, c_void_p]
|
||||
nss.PK11_FindCertFromNickname.restype = c_void_p
|
||||
def PK11_FindCertFromNickname(nickname, wincx):
|
||||
return raise_if_NULL(nss.PK11_FindCertFromNickname(nickname, wincx))
|
||||
|
||||
nss.CERT_DestroyCertificate.argtypes = [c_void_p]
|
||||
nss.CERT_DestroyCertificate.restype = None
|
||||
def CERT_DestroyCertificate(cert):
|
||||
nss.CERT_DestroyCertificate(cert)
|
||||
|
||||
smime.SEC_PKCS7CreateSignedData.argtypes = [c_void_p, c_int, c_void_p,
|
||||
c_int, c_void_p,
|
||||
c_void_p, c_void_p]
|
||||
smime.SEC_PKCS7CreateSignedData.restype = c_void_p
|
||||
def SEC_PKCS7CreateSignedData(cert, certusage, certdb, digestalg, digest, wincx):
|
||||
item = SECItem(0, c_char_p(digest), len(digest))
|
||||
return raise_if_NULL(smime.SEC_PKCS7CreateSignedData(cert, certusage, certdb,
|
||||
digestalg,
|
||||
pointer(item),
|
||||
None, wincx))
|
||||
|
||||
smime.SEC_PKCS7AddSigningTime.argtypes = [c_void_p]
|
||||
smime.SEC_PKCS7AddSigningTime.restype = SECStatus
|
||||
def SEC_PKCS7AddSigningTime(p7):
|
||||
raise_if_not_SECSuccess(smime.SEC_PKCS7AddSigningTime(p7))
|
||||
|
||||
smime.SEC_PKCS7IncludeCertChain.argtypes = [c_void_p, c_void_p]
|
||||
smime.SEC_PKCS7IncludeCertChain.restype = SECStatus
|
||||
def SEC_PKCS7IncludeCertChain(p7, wincx):
|
||||
raise_if_not_SECSuccess(smime.SEC_PKCS7IncludeCertChain(p7, wincx))
|
||||
|
||||
SEC_PKCS7EncoderOutputCallback = CFUNCTYPE(None, c_void_p, c_void_p, c_long)
|
||||
smime.SEC_PKCS7Encode.argtypes = [c_void_p, SEC_PKCS7EncoderOutputCallback,
|
||||
c_void_p, c_void_p, c_void_p, c_void_p]
|
||||
smime.SEC_PKCS7Encode.restype = SECStatus
|
||||
def SEC_PKCS7Encode(p7, bulkkey, wincx):
|
||||
outputChunks = []
|
||||
def callback(chunks, data, len):
|
||||
outputChunks.append(string_at(data, len))
|
||||
callbackWrapper = SEC_PKCS7EncoderOutputCallback(callback)
|
||||
raise_if_not_SECSuccess(smime.SEC_PKCS7Encode(p7, callbackWrapper,
|
||||
None, None, None, wincx))
|
||||
return "".join(outputChunks)
|
||||
|
||||
smime.SEC_PKCS7DestroyContentInfo.argtypes = [c_void_p]
|
||||
smime.SEC_PKCS7DestroyContentInfo.restype = None
|
||||
def SEC_PKCS7DestroyContentInfo(p7):
|
||||
smime.SEC_PKCS7DestroyContentInfo(p7)
|
|
@ -1,78 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python
|
||||
#
|
||||
# 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/.
|
||||
|
||||
# flake8: noqa
|
||||
|
||||
import argparse
|
||||
from base64 import b64encode
|
||||
from hashlib import sha1
|
||||
import sys
|
||||
import ctypes
|
||||
import nss_ctypes
|
||||
|
||||
def nss_create_detached_signature(cert, dataToSign, wincx):
|
||||
certdb = nss_ctypes.CERT_GetDefaultCertDB()
|
||||
p7 = nss_ctypes.SEC_PKCS7CreateSignedData(cert,
|
||||
nss_ctypes.certUsageObjectSigner,
|
||||
certdb,
|
||||
nss_ctypes.SEC_OID_SHA1,
|
||||
sha1(dataToSign).digest(),
|
||||
wincx)
|
||||
try:
|
||||
nss_ctypes.SEC_PKCS7AddSigningTime(p7)
|
||||
nss_ctypes.SEC_PKCS7IncludeCertChain(p7, wincx)
|
||||
return nss_ctypes.SEC_PKCS7Encode(p7, None, wincx)
|
||||
finally:
|
||||
nss_ctypes.SEC_PKCS7DestroyContentInfo(p7)
|
||||
|
||||
# Sign a manifest file
|
||||
def sign_file(in_file, out_file, cert, wincx):
|
||||
contents = in_file.read()
|
||||
in_file.close()
|
||||
|
||||
# generate base64 encoded string of the sha1 digest of the input file
|
||||
in_file_hash = b64encode(sha1(contents).digest())
|
||||
|
||||
# sign the base64 encoded string with the given certificate
|
||||
in_file_signature = nss_create_detached_signature(cert, in_file_hash, wincx)
|
||||
|
||||
# write the content of the output file
|
||||
out_file.write(in_file_signature)
|
||||
out_file.close()
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Sign a B2G app manifest.')
|
||||
parser.add_argument('-d', action='store',
|
||||
required=True, help='NSS database directory')
|
||||
parser.add_argument('-f', action='store',
|
||||
type=argparse.FileType('rb'),
|
||||
required=True, help='password file')
|
||||
parser.add_argument('-k', action='store',
|
||||
required=True, help="nickname of signing cert.")
|
||||
parser.add_argument('-i', action='store', type=argparse.FileType('rb'),
|
||||
required=True, help="input manifest file (unsigned)")
|
||||
parser.add_argument('-o', action='store', type=argparse.FileType('wb'),
|
||||
required=True, help="output manifest file (signed)")
|
||||
args = parser.parse_args()
|
||||
|
||||
db_dir = args.d
|
||||
password = args.f.readline().strip()
|
||||
cert_nickname = args.k
|
||||
cert = None
|
||||
|
||||
try:
|
||||
nss_ctypes.NSS_Init(db_dir)
|
||||
wincx = nss_ctypes.SetPasswordContext(password)
|
||||
cert = nss_ctypes.PK11_FindCertFromNickname(cert_nickname, wincx)
|
||||
sign_file(args.i, args.o, cert, wincx)
|
||||
return 0
|
||||
finally:
|
||||
nss_ctypes.CERT_DestroyCertificate(cert)
|
||||
nss_ctypes.NSS_Shutdown()
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
Двоичный файл не отображается.
Двоичный файл не отображается.
Двоичный файл не отображается.
|
@ -123,7 +123,6 @@ requesttimeoutfactor = 2
|
|||
[test_session_resumption.js]
|
||||
run-sequentially = hardcoded ports
|
||||
[test_signed_apps.js]
|
||||
[test_signed_apps-marketplace.js]
|
||||
[test_signed_dir.js]
|
||||
tags = addons psm
|
||||
[test_sss_enumerate.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче