use crate::model::pk::PemLike;
#[cfg(not(any(feature = "fips", fips)))]
use crate::error::jwt_error::JWTError;
#[cfg(not(any(feature = "fips", fips)))]
use elliptic_curve::pkcs8::{AssociatedOid, DecodePublicKey};
#[cfg(not(any(feature = "fips", fips)))]
use elliptic_curve::sec1::{FromEncodedPoint, ModulusSize, ToEncodedPoint};
#[cfg(not(any(feature = "fips", fips)))]
use elliptic_curve::{CurveArithmetic, JwkParameters, PublicKey};
#[cfg(not(any(feature = "fips", fips)))]
pub fn parse_es_pk<C>(public_key: String) -> Result<PublicKey<C>, JWTError>
where
C: CurveArithmetic + JwkParameters + AssociatedOid,
<C as CurveArithmetic>::AffinePoint: FromEncodedPoint<C>,
<C as elliptic_curve::Curve>::FieldBytesSize: ModulusSize,
<C as CurveArithmetic>::AffinePoint: ToEncodedPoint<C>,
{
match parse_pem(public_key) {
Ok(pem) => match PublicKey::from_public_key_der(pem.contents()) {
Ok(pk) => Ok(pk),
Err(_) => Err(JWTError::EsPublicKeyParseFailed(String::from(
"Error parsing public key.",
))),
},
Err(_) => Err(JWTError::EsPublicKeyParseFailed(String::from(
"Error parsing public key.",
))),
}
}
pub fn parse_pem(mut public_key: String) -> pem::Result<pem::Pem> {
if public_key.has_ecdsa_header() {
public_key = public_key.replace(" ECDSA ", " ");
} else if !public_key.has_pkcs8_header() {
public_key.complete_to_pkcs8_pem()
}
pem::parse(public_key)
}
#[cfg(test)]
#[cfg(not(any(feature = "fips", fips)))]
mod tests {
use super::parse_es_pk;
use elliptic_curve::{pkcs8::DecodePublicKey, PublicKey};
use p256::NistP256;
const ES_PUBLIC_KEY_PEM_ECDSA: &str = "-----BEGIN ECDSA PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERqVXn+o+6zEOpWEsGw5CsB+wd8zO
jxu0uASGpiGP+wYfcc1unyMxcStbDzUjRuObY8DalaCJ9/J6UrkQkZBtZw==
-----END ECDSA PUBLIC KEY-----";
const ES_PUBLIC_KEY_PEM_PKCS8_TRANSFORMED: &str = "-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERqVXn+o+6zEOpWEsGw5CsB+wd8zO
jxu0uASGpiGP+wYfcc1unyMxcStbDzUjRuObY8DalaCJ9/J6UrkQkZBtZw==
-----END PUBLIC KEY-----";
#[test]
fn should_fail_on_a_bad_formed_public_key_for_es256() {
let result = parse_es_pk::<NistP256>(String::from("i am not a valid key"));
assert!(result.is_err());
}
#[test]
fn should_ok_on_ecdsa_header_es_formed_public_key_for_es256() {
let result = parse_es_pk::<NistP256>(String::from(ES_PUBLIC_KEY_PEM_ECDSA));
assert!(result.is_ok());
let expected =
PublicKey::<NistP256>::from_public_key_pem(ES_PUBLIC_KEY_PEM_PKCS8_TRANSFORMED);
assert_eq!(result.unwrap(), expected.unwrap());
}
}