blob: c17b13e6fd5990af5beca6da03aafd9aac0a98b2 [file] [log] [blame]
// Copyright 2026 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use alloc::{boxed::Box, vec::Vec};
use core::{
fmt::{Debug, Formatter, Result as FmtResult},
marker::PhantomData,
};
use bssl_crypto::{digest, ec, ecdsa, ed25519, rsa};
use rustls::{
Error, SignatureAlgorithm, SignatureScheme,
pki_types::{PrivatePkcs1KeyDer, PrivateSec1KeyDer},
sign::{Signer, SigningKey},
};
use crate::{RsaSignatureDigest, pki};
/// A generic `id-rsaEncryption` RSA key
///
/// This key type is only intended for signature
pub(crate) struct RsaPrivateKey(pub rsa::PrivateKey);
impl TryFrom<PrivatePkcs1KeyDer<'_>> for RsaPrivateKey {
type Error = Error;
fn try_from(der: PrivatePkcs1KeyDer) -> Result<Self, Self::Error> {
let der = der.secret_pkcs1_der();
let key = rsa::PrivateKey::from_der_rsa_private_key(der)
.ok_or(Error::General("Cannot parse PKCS#1 key from DER".into()))?;
Ok(Self(key))
}
}
impl Debug for RsaPrivateKey {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_tuple("RsaPrivateKey").finish()
}
}
struct RsaPkcs1Signer<D> {
key: rsa::PrivateKey,
_p: PhantomData<fn() -> D>,
}
impl<D> Debug for RsaPkcs1Signer<D> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_struct("RsaPkcs1Signer").finish()
}
}
impl<D: RsaSignatureDigest> RsaPkcs1Signer<D> {
fn new(key: rsa::PrivateKey) -> Self {
Self {
key,
_p: PhantomData,
}
}
}
impl<D: RsaSignatureDigest> Signer for RsaPkcs1Signer<D> {
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
Ok(self.key.sign_pkcs1::<D>(message))
}
fn scheme(&self) -> SignatureScheme {
match D::ALGORITHM {
pki::DigestAlgorithm::Sha256 => SignatureScheme::RSA_PKCS1_SHA256,
pki::DigestAlgorithm::Sha384 => SignatureScheme::RSA_PKCS1_SHA384,
pki::DigestAlgorithm::Sha512 => SignatureScheme::RSA_PKCS1_SHA512,
}
}
}
struct RsaPssSigner<D> {
key: rsa::PrivateKey,
_p: PhantomData<fn() -> D>,
}
impl<D> Debug for RsaPssSigner<D> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_struct("RsaPssSigner").finish()
}
}
impl<D: RsaSignatureDigest> RsaPssSigner<D> {
fn new(key: rsa::PrivateKey) -> Self {
Self {
key,
_p: PhantomData,
}
}
}
impl<D: RsaSignatureDigest> Signer for RsaPssSigner<D> {
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
Ok(self.key.sign_pss::<D>(message))
}
fn scheme(&self) -> SignatureScheme {
match D::ALGORITHM {
pki::DigestAlgorithm::Sha256 => SignatureScheme::RSA_PSS_SHA256,
pki::DigestAlgorithm::Sha384 => SignatureScheme::RSA_PSS_SHA384,
pki::DigestAlgorithm::Sha512 => SignatureScheme::RSA_PSS_SHA512,
}
}
}
impl SigningKey for RsaPrivateKey {
fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
for offer in offered {
match offer {
SignatureScheme::RSA_PKCS1_SHA1 => continue,
SignatureScheme::RSA_PKCS1_SHA256 => {
return Some(Box::new(RsaPkcs1Signer::<digest::Sha256>::new(
self.0.clone(),
)));
}
SignatureScheme::RSA_PKCS1_SHA384 => {
return Some(Box::new(RsaPkcs1Signer::<digest::Sha384>::new(
self.0.clone(),
)));
}
SignatureScheme::RSA_PKCS1_SHA512 => {
return Some(Box::new(RsaPkcs1Signer::<digest::Sha512>::new(
self.0.clone(),
)));
}
SignatureScheme::RSA_PSS_SHA256 => {
return Some(Box::new(RsaPssSigner::<digest::Sha256>::new(
self.0.clone(),
)));
}
SignatureScheme::RSA_PSS_SHA384 => {
return Some(Box::new(RsaPssSigner::<digest::Sha384>::new(
self.0.clone(),
)));
}
SignatureScheme::RSA_PSS_SHA512 => {
return Some(Box::new(RsaPssSigner::<digest::Sha512>::new(
self.0.clone(),
)));
}
_ => continue,
}
}
None
}
fn algorithm(&self) -> SignatureAlgorithm {
SignatureAlgorithm::RSA
}
}
/// An ECDSA signing key
#[derive(Clone)]
pub(crate) struct EcdsaPrivateKey<C: ec::Curve>(pub ecdsa::PrivateKey<C>);
impl<C: ec::Curve> Debug for EcdsaPrivateKey<C> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_tuple("EcdsaPrivateKey").finish()
}
}
impl<C: ec::Curve> TryFrom<&'_ PrivateSec1KeyDer<'_>> for EcdsaPrivateKey<C> {
type Error = Error;
fn try_from(der: &PrivateSec1KeyDer) -> Result<Self, Self::Error> {
let der = der.secret_sec1_der();
let key = ecdsa::PrivateKey::from_der_ec_private_key(der)
.ok_or(Error::General("Cannot parse Sec1 key from DER".into()))?;
Ok(Self(key))
}
}
macro_rules! ecdsa_signer {
($scheme:path, $curve:path) => {
impl SigningKey for EcdsaPrivateKey<$curve> {
fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
for offer in offered {
match offer {
// We do not support any SHA1 scheme
SignatureScheme::ECDSA_SHA1_Legacy => continue,
$scheme => return Some(Box::new(EcdsaSigner(self.0.clone()))),
_ => continue,
}
}
None
}
fn algorithm(&self) -> SignatureAlgorithm {
SignatureAlgorithm::ECDSA
}
}
impl Signer for EcdsaSigner<$curve> {
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
Ok(self.0.sign(message))
}
fn scheme(&self) -> SignatureScheme {
$scheme
}
}
};
}
ecdsa_signer!(SignatureScheme::ECDSA_NISTP256_SHA256, ec::P256);
ecdsa_signer!(SignatureScheme::ECDSA_NISTP384_SHA384, ec::P384);
struct EcdsaSigner<C: ec::Curve>(ecdsa::PrivateKey<C>);
impl<C: ec::Curve> Debug for EcdsaSigner<C> {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_tuple("EcdsaSigner").finish()
}
}
#[derive(Clone)]
pub(crate) struct EddsaPrivateKey(pub ed25519::PrivateKey);
impl Debug for EddsaPrivateKey {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_tuple("EddsaPrivateKey").finish()
}
}
impl SigningKey for EddsaPrivateKey {
fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
for offer in offered {
if matches!(offer, SignatureScheme::ED25519) {
return Some(Box::new(EddsaSigner(self.0.clone())));
}
}
None
}
fn algorithm(&self) -> SignatureAlgorithm {
SignatureAlgorithm::ED25519
}
}
struct EddsaSigner(ed25519::PrivateKey);
impl Debug for EddsaSigner {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
f.debug_tuple("EddsaSigner").finish()
}
}
impl Signer for EddsaSigner {
fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
Ok(self.0.sign(message).to_vec())
}
fn scheme(&self) -> SignatureScheme {
SignatureScheme::ED25519
}
}