Skip to content

Commit

Permalink
Add delegate interfaces for CertPathBuilder and VerifyCertificateChain.
Browse files Browse the repository at this point in the history
The delegates subsume the functionality of SignaturePolicy, as well as adding a hook to check candidate paths built by CertPathBuilder.

Bug: 634476
Change-Id: I7ed337001e93b5de187a1780562558acf54dc73a
Reviewed-on: https://chromium-review.googlesource.com/582127
Commit-Queue: Eric Roman <eroman@chromium.org>
Reviewed-by: Luke Halliwell <halliwell@chromium.org>
Reviewed-by: Matt Mueller <mattm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#489526}
  • Loading branch information
Eric Roman authored and Commit Bot committed Jul 26, 2017
1 parent 42791d1 commit 5431d70
Show file tree
Hide file tree
Showing 47 changed files with 1,855 additions and 747 deletions.
31 changes: 11 additions & 20 deletions components/cast_certificate/cast_cert_validator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include "net/cert/internal/parsed_certificate.h"
#include "net/cert/internal/path_builder.h"
#include "net/cert/internal/signature_algorithm.h"
#include "net/cert/internal/signature_policy.h"
#include "net/cert/internal/simple_path_builder_delegate.h"
#include "net/cert/internal/trust_store_in_memory.h"
#include "net/cert/internal/verify_certificate_chain.h"
#include "net/cert/internal/verify_signed_data.h"
Expand Down Expand Up @@ -93,19 +93,17 @@ net::der::Input AudioOnlyPolicyOid() {

// Cast certificates rely on RSASSA-PKCS#1 v1.5 with SHA-1 for signatures.
//
// The following signature policy specifies which signature algorithms (and key
// sizes) are acceptable. It is used when verifying a chain of certificates, as
// well as when verifying digital signature using the target certificate's
// SPKI.
// The following delegate will allow signature algorithms of:
//
// This particular policy allows for:
// * ECDSA, RSA-SSA, and RSA-PSS
// * Supported EC curves: P-256, P-384, P-521.
// * Hashes: All SHA hashes including SHA-1 (despite being known weak).
// * RSA keys must have a modulus at least 2048-bits long.
std::unique_ptr<net::SignaturePolicy> CreateCastSignaturePolicy() {
return base::MakeUnique<net::SimpleSignaturePolicy>(2048);
}
//
// It will also require RSA keys have a modulus at least 2048-bits long.
class CastPathBuilderDelegate : public net::SimplePathBuilderDelegate {
public:
CastPathBuilderDelegate() : SimplePathBuilderDelegate(2048) {}
};

class CertVerificationContextImpl : public CertVerificationContext {
public:
Expand All @@ -123,16 +121,10 @@ class CertVerificationContextImpl : public CertVerificationContext {
auto signature_algorithm =
net::SignatureAlgorithm::CreateRsaPkcs1(digest_algorithm);

// Use the same policy as was used for verifying signatures in
// certificates. This will ensure for instance that the key used is at
// least 2048-bits long.
auto signature_policy = CreateCastSignaturePolicy();

net::CertErrors errors;
return net::VerifySignedData(
*signature_algorithm, net::der::Input(data),
net::der::BitString(net::der::Input(signature), 0),
net::der::Input(&spki_), signature_policy.get(), &errors);
net::der::Input(&spki_));
}

std::string GetCommonName() const override { return common_name_; }
Expand Down Expand Up @@ -298,8 +290,7 @@ CastCertError VerifyDeviceCertUsingCustomTrustStore(
intermediate_cert_issuer_source.AddCert(std::move(cert));
}

// Use a signature policy compatible with Cast's PKI.
auto signature_policy = CreateCastSignaturePolicy();
CastPathBuilderDelegate path_builder_delegate;

// Do path building and RFC 5280 compatible certificate verification using the
// two Cast trust anchors and Cast signature policy.
Expand All @@ -308,7 +299,7 @@ CastCertError VerifyDeviceCertUsingCustomTrustStore(
return CastCertError::ERR_UNEXPECTED;
net::CertPathBuilder::Result result;
net::CertPathBuilder path_builder(
target_cert.get(), trust_store, signature_policy.get(), verification_time,
target_cert.get(), trust_store, &path_builder_delegate, verification_time,
net::KeyPurpose::CLIENT_AUTH, net::InitialExplicitPolicy::kFalse,
{net::AnyPolicy()}, net::InitialPolicyMappingInhibit::kFalse,
net::InitialAnyPolicyInhibit::kFalse, &result);
Expand Down
145 changes: 15 additions & 130 deletions components/cast_certificate/cast_cert_validator_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -542,138 +542,23 @@ TEST(VerifyCastDeviceCertTest, PoliciesIcaNoneLeafNone) {
TRUST_STORE_FROM_TEST_FILE, "");
}

// ------------------------------------------------------
// Valid signature using 1024-bit RSA key
// ------------------------------------------------------

// This test vector comes from the NIST test vectors (pkcs1v15sign-vectors.txt),
// PKCS#1 v1.5 Signature Example 1.2.
//
// It is a valid signature using a 1024 bit key and SHA-1.

const uint8_t kEx1Message[] = {
0x85, 0x13, 0x84, 0xcd, 0xfe, 0x81, 0x9c, 0x22, 0xed, 0x6c, 0x4c,
0xcb, 0x30, 0xda, 0xeb, 0x5c, 0xf0, 0x59, 0xbc, 0x8e, 0x11, 0x66,
0xb7, 0xe3, 0x53, 0x0c, 0x4c, 0x23, 0x3e, 0x2b, 0x5f, 0x8f, 0x71,
0xa1, 0xcc, 0xa5, 0x82, 0xd4, 0x3e, 0xcc, 0x72, 0xb1, 0xbc, 0xa1,
0x6d, 0xfc, 0x70, 0x13, 0x22, 0x6b, 0x9e,
};

const uint8_t kEx1Signature[] = {
0x84, 0xfd, 0x2c, 0xe7, 0x34, 0xec, 0x1d, 0xa8, 0x28, 0xd0, 0xf1, 0x5b,
0xf4, 0x9a, 0x87, 0x07, 0xc1, 0x5d, 0x05, 0x94, 0x81, 0x36, 0xde, 0x53,
0x7a, 0x3d, 0xb4, 0x21, 0x38, 0x41, 0x67, 0xc8, 0x6f, 0xae, 0x02, 0x25,
0x87, 0xee, 0x9e, 0x13, 0x7d, 0xae, 0xe7, 0x54, 0x73, 0x82, 0x62, 0x93,
0x2d, 0x27, 0x1c, 0x74, 0x4c, 0x6d, 0x3a, 0x18, 0x9a, 0xd4, 0x31, 0x1b,
0xdb, 0x02, 0x04, 0x92, 0xe3, 0x22, 0xfb, 0xdd, 0xc4, 0x04, 0x06, 0xea,
0x86, 0x0d, 0x4e, 0x8e, 0xa2, 0xa4, 0x08, 0x4a, 0xa9, 0x8b, 0x96, 0x22,
0xa4, 0x46, 0x75, 0x6f, 0xdb, 0x74, 0x0d, 0xdb, 0x3d, 0x91, 0xdb, 0x76,
0x70, 0xe2, 0x11, 0x66, 0x1b, 0xbf, 0x87, 0x09, 0xb1, 0x1c, 0x08, 0xa7,
0x07, 0x71, 0x42, 0x2d, 0x1a, 0x12, 0xde, 0xf2, 0x9f, 0x06, 0x88, 0xa1,
0x92, 0xae, 0xbd, 0x89, 0xe0, 0xf8, 0x96, 0xf8,
};

const uint8_t kEx1PublicKeySpki[] = {
0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81,
0x89, 0x02, 0x81, 0x81, 0x00, 0xa5, 0x6e, 0x4a, 0x0e, 0x70, 0x10, 0x17,
0x58, 0x9a, 0x51, 0x87, 0xdc, 0x7e, 0xa8, 0x41, 0xd1, 0x56, 0xf2, 0xec,
0x0e, 0x36, 0xad, 0x52, 0xa4, 0x4d, 0xfe, 0xb1, 0xe6, 0x1f, 0x7a, 0xd9,
0x91, 0xd8, 0xc5, 0x10, 0x56, 0xff, 0xed, 0xb1, 0x62, 0xb4, 0xc0, 0xf2,
0x83, 0xa1, 0x2a, 0x88, 0xa3, 0x94, 0xdf, 0xf5, 0x26, 0xab, 0x72, 0x91,
0xcb, 0xb3, 0x07, 0xce, 0xab, 0xfc, 0xe0, 0xb1, 0xdf, 0xd5, 0xcd, 0x95,
0x08, 0x09, 0x6d, 0x5b, 0x2b, 0x8b, 0x6d, 0xf5, 0xd6, 0x71, 0xef, 0x63,
0x77, 0xc0, 0x92, 0x1c, 0xb2, 0x3c, 0x27, 0x0a, 0x70, 0xe2, 0x59, 0x8e,
0x6f, 0xf8, 0x9d, 0x19, 0xf1, 0x05, 0xac, 0xc2, 0xd3, 0xf0, 0xcb, 0x35,
0xf2, 0x92, 0x80, 0xe1, 0x38, 0x6b, 0x6f, 0x64, 0xc4, 0xef, 0x22, 0xe1,
0xe1, 0xf2, 0x0d, 0x0c, 0xe8, 0xcf, 0xfb, 0x22, 0x49, 0xbd, 0x9a, 0x21,
0x37, 0x02, 0x03, 0x01, 0x00, 0x01,
};

// Tests that a valid signature fails, because it uses a 1024-bit RSA key (too
// weak).
TEST(VerifyCastDeviceCertTest, VerifySignature1024BitRsa) {
auto context =
CertVerificationContextImplForTest(CreateString(kEx1PublicKeySpki));

EXPECT_FALSE(context->VerifySignatureOverData(CreateString(kEx1Signature),
CreateString(kEx1Message),
net::DigestAlgorithm::Sha1));
// Tests verifying a certificate chain where the leaf certificate has a
// 1024-bit RSA key. Verification should fail since the target's key is
// too weak.
TEST(VerifyCastDeviceCertTest, DeviceCertHas1024BitRsaKey) {
RunTest(CastCertError::ERR_CERTS_VERIFY_GENERIC, "RSA 1024 Device Cert",
CastDeviceCertPolicy::NONE, "certificates/rsa1024_device_cert.pem",
AprilFirst2016(), TRUST_STORE_FROM_TEST_FILE, "");
}

// ------------------------------------------------------
// Valid signature using 2048-bit RSA key
// ------------------------------------------------------

// This test vector was generated (using WebCrypto). It is a valid signature
// using a 2048-bit RSA key, RSASSA PKCS#1 v1.5 with SHA-1.

const uint8_t kEx2Message[] = {
// "hello"
0x68, 0x65, 0x6c, 0x6c, 0x6f,
};

const uint8_t kEx2Signature[] = {
0xc1, 0x21, 0x84, 0xe1, 0x62, 0x0e, 0x59, 0x52, 0x5b, 0xa4, 0x10, 0x1e,
0x11, 0x80, 0x5b, 0x9e, 0xcb, 0xa0, 0x20, 0x78, 0x29, 0xfc, 0xc0, 0x9a,
0xd9, 0x48, 0x90, 0x81, 0x03, 0xa9, 0xc0, 0x2f, 0x0a, 0xc4, 0x20, 0x34,
0xb5, 0xdb, 0x19, 0x04, 0xec, 0x94, 0x9b, 0xba, 0x48, 0x43, 0xf3, 0x5a,
0x15, 0x56, 0xfc, 0x4a, 0x87, 0x79, 0xf8, 0x50, 0xff, 0x5d, 0x66, 0x25,
0xdc, 0xa5, 0xd8, 0xe8, 0x9f, 0x5a, 0x73, 0x79, 0x6f, 0x5d, 0x99, 0xe0,
0xd5, 0xa5, 0x84, 0x49, 0x20, 0x3c, 0xe2, 0xa3, 0xd0, 0x69, 0x31, 0x2c,
0x13, 0xaf, 0x15, 0xd9, 0x10, 0x0d, 0x6f, 0xdd, 0x9d, 0x62, 0x5d, 0x7b,
0xe1, 0x1a, 0x48, 0x59, 0xaf, 0xf7, 0xbe, 0x87, 0x92, 0x60, 0x5d, 0x1a,
0xb5, 0xfe, 0x27, 0x38, 0x02, 0x20, 0xe9, 0xaf, 0x04, 0x57, 0xd3, 0x3b,
0x70, 0x04, 0x63, 0x5b, 0xc6, 0x5d, 0x83, 0xe2, 0xaf, 0x02, 0xb4, 0xef,
0x1c, 0x33, 0x54, 0x38, 0xf8, 0xb5, 0x19, 0xa8, 0x88, 0xdd, 0x1d, 0x96,
0x1c, 0x5e, 0x54, 0x80, 0xde, 0x7b, 0xb6, 0x29, 0xb8, 0x6b, 0xea, 0x47,
0xe5, 0xf1, 0x7e, 0xed, 0xe1, 0x91, 0xc8, 0xb8, 0x54, 0xd9, 0x1e, 0xfd,
0x07, 0x10, 0xbd, 0xa9, 0xd4, 0x93, 0x5e, 0x65, 0x8b, 0x6b, 0x46, 0x93,
0x4b, 0x60, 0x2a, 0x26, 0xf0, 0x1b, 0x4e, 0xca, 0x04, 0x82, 0xc0, 0x8d,
0xb1, 0xa5, 0xa8, 0x70, 0xdd, 0x66, 0x68, 0x95, 0x09, 0xb4, 0x85, 0x62,
0xf5, 0x17, 0x04, 0x48, 0xb4, 0x9d, 0x66, 0x2b, 0x25, 0x82, 0x7e, 0x99,
0x3e, 0xa1, 0x11, 0x63, 0xc3, 0xdf, 0x10, 0x20, 0x52, 0x56, 0x32, 0x35,
0xa9, 0x36, 0xde, 0x2a, 0xac, 0x10, 0x0d, 0x75, 0x21, 0xed, 0x5b, 0x38,
0xb6, 0xb5, 0x1e, 0xb5, 0x5b, 0x9a, 0x72, 0xd5, 0xf8, 0x1a, 0xd3, 0x91,
0xb8, 0x29, 0x0e, 0x58,
};

const uint8_t kEx2PublicKeySpki[] = {
0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xcf, 0xde, 0xa5,
0x2e, 0x9d, 0x38, 0x62, 0x72, 0x47, 0x84, 0x8f, 0x2e, 0xa5, 0xe3, 0xd6,
0x34, 0xb0, 0xf9, 0x79, 0xa9, 0x10, 0x63, 0xa9, 0x93, 0x5a, 0xa1, 0xb9,
0xa3, 0x03, 0xd3, 0xcd, 0x9d, 0x84, 0x7d, 0xb6, 0x92, 0x47, 0xb4, 0x7d,
0x4a, 0xe8, 0x3a, 0x4b, 0xc5, 0xf6, 0x35, 0x6f, 0x18, 0x72, 0xf3, 0xbc,
0xd2, 0x1c, 0x7a, 0xd2, 0xe5, 0xdf, 0xcf, 0xb9, 0xac, 0x28, 0xd3, 0x49,
0x2a, 0x4f, 0x08, 0x62, 0xb9, 0xf1, 0xaa, 0x3d, 0x76, 0xe3, 0xa9, 0x96,
0x32, 0x24, 0x94, 0x9e, 0x88, 0xf8, 0x5e, 0xc3, 0x3c, 0x14, 0x32, 0x86,
0x72, 0xa2, 0x34, 0x3d, 0x41, 0xd0, 0xb2, 0x01, 0x99, 0x01, 0xf3, 0x93,
0xa3, 0x76, 0x5a, 0xff, 0x42, 0x28, 0x54, 0xe0, 0xcc, 0x4c, 0xcd, 0x2d,
0x3b, 0x0b, 0x47, 0xcc, 0xc2, 0x75, 0x02, 0xc1, 0xb7, 0x0b, 0x37, 0x65,
0xe6, 0x0d, 0xe4, 0xc3, 0x85, 0x86, 0x29, 0x3c, 0x77, 0xce, 0xb0, 0x34,
0xa9, 0x03, 0xe9, 0x13, 0xbe, 0x97, 0x1e, 0xfd, 0xeb, 0x0d, 0x60, 0xc2,
0xb3, 0x19, 0xa1, 0x75, 0x72, 0x57, 0x3f, 0x5d, 0x0e, 0x75, 0xac, 0x10,
0x96, 0xad, 0x95, 0x67, 0x9f, 0xa2, 0x84, 0x15, 0x6a, 0x61, 0xb1, 0x47,
0xd1, 0x24, 0x78, 0xb4, 0x40, 0x2b, 0xc3, 0x5c, 0x73, 0xd4, 0xc1, 0x8d,
0x12, 0xf1, 0x3f, 0xb4, 0x93, 0x17, 0xfe, 0x5d, 0xbf, 0x39, 0xf2, 0x45,
0xf9, 0xcf, 0x38, 0x44, 0x40, 0x5b, 0x47, 0x2a, 0xbf, 0xb9, 0xac, 0xa6,
0x14, 0xb6, 0x1b, 0xe3, 0xa8, 0x14, 0xf8, 0xfe, 0x47, 0x67, 0xea, 0x90,
0x51, 0x12, 0xcf, 0x5e, 0x28, 0xec, 0x92, 0x83, 0x7c, 0xc6, 0x29, 0x9f,
0x12, 0x29, 0x88, 0x49, 0xf7, 0xb7, 0xed, 0x5e, 0x3a, 0x78, 0xd6, 0x8a,
0xba, 0x42, 0x6e, 0x0a, 0xf4, 0x0d, 0xc1, 0xc0, 0x8f, 0xdb, 0x26, 0x41,
0x57, 0x02, 0x03, 0x01, 0x00, 0x01,
};

// Tests that a valid signature using 2048-bit key succeeds.
TEST(VerifyCastDeviceCertTest, VerifySignature2048BitRsa) {
auto context =
CertVerificationContextImplForTest(CreateString(kEx2PublicKeySpki));

EXPECT_TRUE(context->VerifySignatureOverData(CreateString(kEx2Signature),
CreateString(kEx2Message),
net::DigestAlgorithm::Sha1));
// Tests verifying a certificate chain where the leaf certificate has a
// 2048-bit RSA key, and then verifying signed data (both SHA1 and SHA256)
// for it.
TEST(VerifyCastDeviceCertTest, DeviceCertHas2048BitRsaKey) {
RunTest(CastCertError::OK, "RSA 2048 Device Cert", CastDeviceCertPolicy::NONE,
"certificates/rsa2048_device_cert.pem", AprilFirst2016(),
TRUST_STORE_FROM_TEST_FILE,
"signeddata/rsa2048_device_cert_data.pem");
}

} // namespace
Expand Down
28 changes: 11 additions & 17 deletions components/cast_certificate/cast_crl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include "net/cert/internal/parsed_certificate.h"
#include "net/cert/internal/path_builder.h"
#include "net/cert/internal/signature_algorithm.h"
#include "net/cert/internal/signature_policy.h"
#include "net/cert/internal/simple_path_builder_delegate.h"
#include "net/cert/internal/trust_store_in_memory.h"
#include "net/cert/internal/verify_certificate_chain.h"
#include "net/cert/internal/verify_signed_data.h"
Expand Down Expand Up @@ -87,13 +87,6 @@ bool ConvertTimeSeconds(uint64_t seconds,
generalized_time);
}

// Specifies the signature verification policy.
// The required algorithms are:
// RSASSA PKCS#1 v1.5 with SHA-256, using RSA keys 2048-bits or longer.
std::unique_ptr<net::SignaturePolicy> CreateCastSignaturePolicy() {
return base::MakeUnique<net::SimpleSignaturePolicy>(2048);
}

// Verifies the CRL is signed by a trusted CRL authority at the time the CRL
// was issued. Verifies the signature of |tbs_crl| is valid based on the
// certificate and signature in |crl|. The validity of |tbs_crl| is verified
Expand Down Expand Up @@ -122,16 +115,12 @@ bool VerifyCRL(const Crl& crl,
net::der::Input(base::StringPiece(crl.signature())), 0);

// Verify the signature.
auto signature_policy = CreateCastSignaturePolicy();
std::unique_ptr<net::SignatureAlgorithm> signature_algorithm_type =
net::SignatureAlgorithm::CreateRsaPkcs1(net::DigestAlgorithm::Sha256);
net::CertErrors verify_errors;
if (!VerifySignedData(*signature_algorithm_type,
net::der::Input(&crl.tbs_crl()),
signature_value_bit_string, parsed_cert->tbs().spki_tlv,
signature_policy.get(), &verify_errors)) {
VLOG(2) << "CRL - Signature verification failed:\n"
<< verify_errors.ToDebugString();
if (!VerifySignedData(
*signature_algorithm_type, net::der::Input(&crl.tbs_crl()),
signature_value_bit_string, parsed_cert->tbs().spki_tlv)) {
VLOG(2) << "CRL - Signature verification failed";
return false;
}

Expand All @@ -141,9 +130,14 @@ bool VerifyCRL(const Crl& crl,
VLOG(2) << "CRL - Unable to parse verification time.";
return false;
}

// SimplePathBuilderDelegate will enforce required signature algorithms of
// RSASSA PKCS#1 v1.5 with SHA-256, and RSA keys 2048-bits or longer.
net::SimplePathBuilderDelegate path_builder_delegate(2048);

net::CertPathBuilder::Result result;
net::CertPathBuilder path_builder(
parsed_cert.get(), trust_store, signature_policy.get(), verification_time,
parsed_cert.get(), trust_store, &path_builder_delegate, verification_time,
net::KeyPurpose::ANY_EKU, net::InitialExplicitPolicy::kFalse,
{net::AnyPolicy()}, net::InitialPolicyMappingInhibit::kFalse,
net::InitialAnyPolicyInhibit::kFalse, &result);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/python
# Copyright (c) 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
Helper code to generate SHA1 and SHA256 signatures given a private key.
Expects CWD to be the scripts directory.
"""

import base64
import os
import subprocess
import sys
sys.path += ['../../../../../net/data/verify_certificate_chain_unittest']

import common


def sign_data(key_path, data_to_sign, digest):
"""Returns the signature of |data_to_sign| using the key at |key_path| and
the digest algorithm |digest|. The |digest| parameter should be either
"sha256" or "sha1"""

data_to_sign_path = 'out/tmp_data_to_sign'
signed_data_path = 'out/tmp_signed_data'

common.write_string_to_file(data_to_sign, data_to_sign_path)

subprocess.check_call(['openssl', 'dgst', '-' + digest,
'-sign', key_path,
'-out', signed_data_path,
data_to_sign_path ])

signature = common.read_file_to_string(signed_data_path)

# Delete the temporary files.
os.remove(data_to_sign_path)
os.remove(signed_data_path)

return signature


def create_signed_data(key_path, signed_data_pem_path, cert_path):
# Use some random data as the message.
data_to_sign = os.urandom(256)

sha1_signature = sign_data(key_path, data_to_sign, 'sha1')
sha256_signature = sign_data(key_path, data_to_sign, 'sha256')

# Write a final PEM file which incorporates the message, and signatures.
signed_data_pem_data = """
These signatures were generated using the device certificate key from:
%s
The data being signed is a bunch of random data.
-----BEGIN MESSAGE-----
%s
-----END MESSAGE-----
Signature Algorithm: RSASSA PKCS#1 v1.5 with SHA1
-----BEGIN SIGNATURE SHA1-----
%s
-----END SIGNATURE SHA1-----
Signature Algorithm: RSASSA PKCS#1 v1.5 with SHA256
-----BEGIN SIGNATURE SHA256-----
%s
-----END SIGNATURE SHA256----- """ % (cert_path,
base64.b64encode(data_to_sign),
base64.b64encode(sha1_signature),
base64.b64encode(sha256_signature))

common.write_string_to_file(signed_data_pem_data, signed_data_pem_path)
Loading

0 comments on commit 5431d70

Please sign in to comment.