From 892efa03c2e745cee5c8049d9304f1e708ba2d7a Mon Sep 17 00:00:00 2001 From: Richard Zak Date: Tue, 27 Sep 2022 16:04:57 -0400 Subject: [PATCH] spki.rs completed Signed-off-by: Richard Zak --- Cargo.lock | 3 +- src/crypto/spki.rs | 72 ++++++++++++++++++++++++---------------------- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca3173c3..6a08318c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1077,7 +1077,8 @@ dependencies = [ [[package]] name = "ring" version = "0.16.20" -source = "git+https://github.com/ibm/ring.git?branch=ppc-0.16.20#3f8f04a1057e286f3b8c5b9e39c9f795b15743cc" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" dependencies = [ "cc", "libc", diff --git a/src/crypto/spki.rs b/src/crypto/spki.rs index ecf910c7..34ed553c 100644 --- a/src/crypto/spki.rs +++ b/src/crypto/spki.rs @@ -1,20 +1,18 @@ // SPDX-FileCopyrightText: 2022 Profian Inc. // SPDX-License-Identifier: AGPL-3.0-only +use anyhow::{anyhow, bail, Result}; use const_oid::ObjectIdentifier; use der::{asn1::AnyRef, Sequence}; -use ring::signature::VerificationAlgorithm as VerAlg; -use ring::signature::*; +use rsa::pkcs1::DecodeRsaPublicKey; use spki::{AlgorithmIdentifier, SubjectPublicKeyInfo}; use const_oid::db::rfc5912::{ - ECDSA_WITH_SHA_256, ECDSA_WITH_SHA_384, ID_EC_PUBLIC_KEY as ECPK, ID_MGF_1, ID_RSASSA_PSS, + ECDSA_WITH_SHA_256, ECDSA_WITH_SHA_384, ID_EC_PUBLIC_KEY as ECPK, ID_RSASSA_PSS, ID_SHA_256 as SHA256, ID_SHA_384 as SHA384, ID_SHA_512 as SHA512, RSA_ENCRYPTION as RSA, SECP_256_R_1 as P256, SECP_384_R_1 as P384, }; -use anyhow::{anyhow, Result}; - const ES256: (ObjectIdentifier, Option>) = (ECDSA_WITH_SHA_256, None); const ES384: (ObjectIdentifier, Option>) = (ECDSA_WITH_SHA_384, None); @@ -46,44 +44,50 @@ pub trait SubjectPublicKeyInfoExt { impl<'a> SubjectPublicKeyInfoExt for SubjectPublicKeyInfo<'a> { fn verify(&self, body: &[u8], algo: AlgorithmIdentifier<'_>, sign: &[u8]) -> Result<()> { - let alg: &'static dyn VerAlg = match (self.algorithm.oids()?, (algo.oid, algo.parameters)) { - ((ECPK, Some(P256)), ES256) => &ECDSA_P256_SHA256_ASN1, - ((ECPK, Some(P384)), ES384) => &ECDSA_P384_SHA384_ASN1, + match (self.algorithm.oids()?, (algo.oid, algo.parameters)) { + ((ECPK, Some(P256)), ES256) => { + use p256::ecdsa::signature::Verifier; + let vkey = p256::ecdsa::VerifyingKey::from_sec1_bytes(self.subject_public_key)?; + let sig = p256::ecdsa::Signature::from_der(sign)?; + return Ok(vkey.verify(&body, &sig)?); + } + ((ECPK, Some(P384)), ES384) => { + use p384::ecdsa::signature::Verifier; + let vkey = p384::ecdsa::VerifyingKey::from_sec1_bytes(self.subject_public_key)?; + let sig = p384::ecdsa::Signature::from_der(sign)?; + return Ok(vkey.verify(&body, &sig).unwrap()); + } ((RSA, None), (ID_RSASSA_PSS, Some(p))) => { + use signature::{Signature, Verifier}; // Decompose the RSA PSS parameters. let RsaSsaPssParams { - hash_algorithm: hash, + hash_algorithm: _hash, mask_algorithm: mask, - salt_length: salt, - trailer_field: tfld, + salt_length: _salt, + trailer_field: _tfld, } = p.decode_into()?; - // Validate the sanity of the mask algorithm. - let algo = match (mask.oid, mask.parameters) { - (ID_MGF_1, Some(p)) => { - let p = p.decode_into::>()?; - match (p.oids()?, salt, tfld) { - ((SHA256, None), 32, 1) => Ok(SHA256), - ((SHA384, None), 48, 1) => Ok(SHA384), - ((SHA512, None), 64, 1) => Ok(SHA512), - _ => Err(anyhow!("unsupported")), - } - } - _ => Err(anyhow!("unsupported")), - }?; + let pkey = rsa::RsaPublicKey::from_pkcs1_der(self.subject_public_key)?; + let s = rsa::pss::Signature::from_bytes(sign)?; - // Prepare for validation. - match (hash.oids()?, algo) { - ((SHA256, None), SHA256) => &RSA_PSS_2048_8192_SHA256, - ((SHA384, None), SHA384) => &RSA_PSS_2048_8192_SHA384, - ((SHA512, None), SHA512) => &RSA_PSS_2048_8192_SHA512, - _ => return Err(anyhow!("unsupported")), + let p2 = mask.parameters.ok_or(anyhow!("bad RSA parameters"))?; + match p2.decode_into::>()?.oid { + SHA256 => { + let vkey = rsa::pss::VerifyingKey::::new(pkey); + return Ok(vkey.verify(body, &s)?); + } + SHA384 => { + let vkey = rsa::pss::VerifyingKey::::new(pkey); + return Ok(vkey.verify(body, &s)?); + } + SHA512 => { + let vkey = rsa::pss::VerifyingKey::::new(pkey); + return Ok(vkey.verify(body, &s)?); + } + _ => bail!("unsupported"), } } _ => return Err(anyhow!("unsupported")), - }; - - let upk = UnparsedPublicKey::new(alg, self.subject_public_key); - Ok(upk.verify(body, sign)?) + } } }