0

Introduce a function to format a DER-encoded SPKI for UI

This introduces x509_certificate_model::ProcessRawSubjectPublicKeyInfo
which takes a DER-encoded X.509 SubjectPublicKeyInfo as input, and
returns a string intended for displaying the public key represented by
it.

It will be used in the UI code for the Chrome OS built-in certificate
provisioning feature. When a certificate provisioning process is in
progress, only a key pair is on the device and not a certificate (yet).
This function will be used to display the public key of the key pair on
the UI.

Bug: 1045895, 1081396
Change-Id: I8428dec1a03ac1fdc3edffdaeeda304be0cdb9be
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2036053
Commit-Queue: Pavol Marko <pmarko@chromium.org>
Reviewed-by: David Benjamin <davidben@chromium.org>
Cr-Commit-Position: refs/heads/master@{#768551}
This commit is contained in:
Pavol Marko
2020-05-14 00:17:03 +00:00
committed by Commit Bot
parent 0643814f5c
commit 701cae5de1
5 changed files with 42 additions and 16 deletions

@ -5,6 +5,7 @@
#include "chrome/common/net/x509_certificate_model_nss.h"
#include <cert.h>
#include <certt.h>
#include <cms.h>
#include <hasht.h>
#include <keyhi.h> // SECKEY_DestroyPrivateKey
@ -29,6 +30,7 @@
#include "chrome/third_party/mozilla_security_manager/nsNSSCertificate.h"
#include "chrome/third_party/mozilla_security_manager/nsUsageArrayHelper.h"
#include "components/url_formatter/url_formatter.h"
#include "crypto/nss_key_util.h"
#include "crypto/nss_util.h"
#include "crypto/scoped_nss_types.h"
#include "net/cert/x509_util_nss.h"
@ -303,6 +305,14 @@ string ProcessSubjectPublicKeyInfo(CERTCertificate* cert_handle) {
return psm::ProcessSubjectPublicKeyInfo(&cert_handle->subjectPublicKeyInfo);
}
string ProcessRawSubjectPublicKeyInfo(base::span<const uint8_t> spki_der) {
crypto::ScopedCERTSubjectPublicKeyInfo spki =
crypto::DecodeSubjectPublicKeyInfoNSS(spki_der);
if (!spki)
return std::string();
return psm::ProcessSubjectPublicKeyInfo(spki.get());
}
string ProcessRawBitsSignatureWrap(CERTCertificate* cert_handle) {
return ProcessRawBits(cert_handle->signatureWrap.signature.data,
cert_handle->signatureWrap.signature.len);

@ -10,6 +10,7 @@
#include <string>
#include <vector>
#include "base/containers/span.h"
#include "net/cert/cert_type.h"
#include "net/cert/scoped_nss_types.h"
@ -89,8 +90,15 @@ std::string ProcessSecAlgorithmSignature(CERTCertificate* cert_handle);
std::string ProcessSecAlgorithmSubjectPublicKey(CERTCertificate* cert_handle);
std::string ProcessSecAlgorithmSignatureWrap(CERTCertificate* cert_handle);
// Formats the public key from the X.509 SubjectPublicKeyInfo extracted from
// |cert_handle| as a string for displaying.
std::string ProcessSubjectPublicKeyInfo(CERTCertificate* cert_handle);
// Parses |public_key_spki_der| as a DER-encoded X.509 SubjectPublicKeyInfo,
// then formats the public key as a string for displaying.
std::string ProcessRawSubjectPublicKeyInfo(
base::span<const uint8_t> public_key_spki_der);
std::string ProcessRawBitsSignatureWrap(CERTCertificate* cert_handle);
// For host values, if they contain IDN Punycode-encoded A-labels, this will

@ -20,25 +20,10 @@ namespace crypto {
namespace {
struct PublicKeyInfoDeleter {
inline void operator()(CERTSubjectPublicKeyInfo* spki) {
SECKEY_DestroySubjectPublicKeyInfo(spki);
}
};
typedef std::unique_ptr<CERTSubjectPublicKeyInfo, PublicKeyInfoDeleter>
ScopedPublicKeyInfo;
// Decodes |input| as a SubjectPublicKeyInfo and returns a SECItem containing
// the CKA_ID of that public key or nullptr on error.
ScopedSECItem MakeIDFromSPKI(base::span<const uint8_t> input) {
// First, decode and save the public key.
SECItem key_der;
key_der.type = siBuffer;
key_der.data = const_cast<unsigned char*>(input.data());
key_der.len = input.size();
ScopedPublicKeyInfo spki(SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der));
ScopedCERTSubjectPublicKeyInfo spki = DecodeSubjectPublicKeyInfoNSS(input);
if (!spki)
return nullptr;
@ -190,4 +175,17 @@ ScopedSECKEYPrivateKey FindNSSKeyFromPublicKeyInfoInSlot(
PK11_FindKeyByKeyID(slot, cka_id.get(), nullptr));
}
ScopedCERTSubjectPublicKeyInfo DecodeSubjectPublicKeyInfoNSS(
base::span<const uint8_t> input) {
// First, decode and save the public key.
SECItem key_der;
key_der.type = siBuffer;
key_der.data = const_cast<unsigned char*>(input.data());
key_der.len = input.size();
ScopedCERTSubjectPublicKeyInfo spki(
SECKEY_DecodeDERSubjectPublicKeyInfo(&key_der));
return spki;
}
} // namespace crypto

@ -61,6 +61,11 @@ CRYPTO_EXPORT ScopedSECKEYPrivateKey
FindNSSKeyFromPublicKeyInfoInSlot(base::span<const uint8_t> input,
PK11SlotInfo* slot);
// Decodes |input| as a DER-encoded X.509 SubjectPublicKeyInfo and returns the
// NSS representation of it.
CRYPTO_EXPORT ScopedCERTSubjectPublicKeyInfo
DecodeSubjectPublicKeyInfoNSS(base::span<const uint8_t> input);
} // namespace crypto
#endif // CRYPTO_NSS_KEY_UTIL_H_

@ -7,6 +7,7 @@
#include <keyhi.h>
#include <nss.h>
#include <nss/certt.h>
#include <pk11pub.h>
#include <plarena.h>
@ -57,6 +58,10 @@ typedef std::unique_ptr<SECItem,
typedef std::unique_ptr<PLArenaPool,
NSSDestroyer1<PLArenaPool, PORT_FreeArena, PR_FALSE>>
ScopedPLArenaPool;
typedef std::unique_ptr<
CERTSubjectPublicKeyInfo,
NSSDestroyer<CERTSubjectPublicKeyInfo, SECKEY_DestroySubjectPublicKeyInfo>>
ScopedCERTSubjectPublicKeyInfo;
} // namespace crypto