use super::der::*;
use super::pem::*;
use crate::ecc::curves::{PublicKey as EcPublicKey, SecretKey as EcSecretKey};
use crate::ecc::eddsa::{Ed25519PublicKey, Ed25519SecretKey};
use crate::rsa::bigint::BigInt;
use crate::rsa::rsa::{RsaPublicKey, RsaSecretKey};
impl RsaPublicKey {
pub fn to_pkcs1_der(&self) -> Vec<u8> {
let n_bytes = self.n.to_be_bytes(self.n.byte_len());
let e_bytes = self.e.to_be_bytes(self.e.byte_len());
let mut inner = DerEncoder::new();
inner.integer(&n_bytes);
inner.integer(&e_bytes);
let content = inner.finish();
let mut outer = DerEncoder::new();
outer.sequence(&content);
outer.finish()
}
pub fn from_pkcs1_der(der: &[u8]) -> Option<Self> {
let mut dec = DerDecoder::new(der);
let mut seq = dec.read_sequence()?;
let n = BigInt::from_be_bytes(seq.read_integer()?);
let e = BigInt::from_be_bytes(seq.read_integer()?);
if !seq.is_empty() {
return None;
}
Some(Self { n, e })
}
pub fn to_spki_der(&self) -> Vec<u8> {
let pkcs1 = self.to_pkcs1_der();
let mut algo = DerEncoder::new();
algo.oid(OID_RSA);
algo.null();
let algo_bytes = algo.finish();
let mut inner = DerEncoder::new();
inner.sequence(&algo_bytes);
inner.bit_string(&pkcs1);
let content = inner.finish();
let mut outer = DerEncoder::new();
outer.sequence(&content);
outer.finish()
}
pub fn from_spki_der(der: &[u8]) -> Option<Self> {
let mut dec = DerDecoder::new(der);
let mut seq = dec.read_sequence()?;
let mut algo_seq = seq.read_sequence()?;
let oid = algo_seq.read_oid()?;
if oid != OID_RSA {
return None;
}
algo_seq.read_null()?;
let pk_bits = seq.read_bit_string()?;
Self::from_pkcs1_der(pk_bits)
}
pub fn to_pkcs1_pem(&self) -> String {
pem_encode("RSA PUBLIC KEY", &self.to_pkcs1_der())
}
pub fn from_pkcs1_pem(pem: &str) -> Option<Self> {
Self::from_pkcs1_der(&pem_decode("RSA PUBLIC KEY", pem)?)
}
pub fn to_spki_pem(&self) -> String {
pem_encode("PUBLIC KEY", &self.to_spki_der())
}
pub fn from_spki_pem(pem: &str) -> Option<Self> {
Self::from_spki_der(&pem_decode("PUBLIC KEY", pem)?)
}
}
impl RsaSecretKey {
pub fn to_pkcs1_der(&self) -> Vec<u8> {
let n = self.n.to_be_bytes(self.n.byte_len());
let e_val = BigInt::from_be_bytes(&[0x01, 0x00, 0x01]); let e = e_val.to_be_bytes(e_val.byte_len());
let d = self.d.to_be_bytes(self.d.byte_len());
let p = self.p.to_be_bytes(self.p.byte_len());
let q = self.q.to_be_bytes(self.q.byte_len());
let dp = self.dp.to_be_bytes(self.dp.byte_len());
let dq = self.dq.to_be_bytes(self.dq.byte_len());
let qinv = self.qinv.to_be_bytes(self.qinv.byte_len());
let mut inner = DerEncoder::new();
inner.integer_u64(0); inner.integer(&n);
inner.integer(&e);
inner.integer(&d);
inner.integer(&p);
inner.integer(&q);
inner.integer(&dp);
inner.integer(&dq);
inner.integer(&qinv);
let content = inner.finish();
let mut outer = DerEncoder::new();
outer.sequence(&content);
outer.finish()
}
pub fn from_pkcs1_der(der: &[u8]) -> Option<Self> {
let mut dec = DerDecoder::new(der);
let mut seq = dec.read_sequence()?;
let version = seq.read_integer_u64()?;
if version != 0 {
return None;
} let n = BigInt::from_be_bytes(seq.read_integer()?);
let _e = seq.read_integer()?; let d = BigInt::from_be_bytes(seq.read_integer()?);
let p = BigInt::from_be_bytes(seq.read_integer()?);
let q = BigInt::from_be_bytes(seq.read_integer()?);
let dp = BigInt::from_be_bytes(seq.read_integer()?);
let dq = BigInt::from_be_bytes(seq.read_integer()?);
let qinv = BigInt::from_be_bytes(seq.read_integer()?);
Some(Self {
n,
d,
p,
q,
dp,
dq,
qinv,
})
}
pub fn to_pkcs1_pem(&self) -> String {
pem_encode("RSA PRIVATE KEY", &self.to_pkcs1_der())
}
pub fn from_pkcs1_pem(pem: &str) -> Option<Self> {
Self::from_pkcs1_der(&pem_decode("RSA PRIVATE KEY", pem)?)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum EcCurve {
P256,
P384,
P521,
Secp256k1,
BrainpoolP256r1,
BrainpoolP384r1,
BrainpoolP512r1,
}
impl EcCurve {
fn oid(self) -> &'static [u8] {
match self {
EcCurve::P256 => OID_SECP256R1,
EcCurve::P384 => OID_SECP384R1,
EcCurve::P521 => OID_SECP521R1,
EcCurve::Secp256k1 => OID_SECP256K1,
EcCurve::BrainpoolP256r1 => OID_BRAINPOOL_P256R1,
EcCurve::BrainpoolP384r1 => OID_BRAINPOOL_P384R1,
EcCurve::BrainpoolP512r1 => OID_BRAINPOOL_P512R1,
}
}
fn from_oid(oid: &[u8]) -> Option<Self> {
match oid {
x if x == OID_SECP256R1 => Some(EcCurve::P256),
x if x == OID_SECP384R1 => Some(EcCurve::P384),
x if x == OID_SECP521R1 => Some(EcCurve::P521),
x if x == OID_SECP256K1 => Some(EcCurve::Secp256k1),
x if x == OID_BRAINPOOL_P256R1 => Some(EcCurve::BrainpoolP256r1),
x if x == OID_BRAINPOOL_P384R1 => Some(EcCurve::BrainpoolP384r1),
x if x == OID_BRAINPOOL_P512R1 => Some(EcCurve::BrainpoolP512r1),
_ => None,
}
}
}
impl EcPublicKey {
pub fn to_spki_der(&self, curve: EcCurve) -> Vec<u8> {
let mut algo = DerEncoder::new();
algo.oid(OID_EC_PUBLIC_KEY);
algo.oid(curve.oid());
let algo_bytes = algo.finish();
let mut inner = DerEncoder::new();
inner.sequence(&algo_bytes);
inner.bit_string(&self.bytes);
let content = inner.finish();
let mut outer = DerEncoder::new();
outer.sequence(&content);
outer.finish()
}
pub fn from_spki_der(der: &[u8]) -> Option<(Self, EcCurve)> {
let mut dec = DerDecoder::new(der);
let mut seq = dec.read_sequence()?;
let mut algo_seq = seq.read_sequence()?;
let oid = algo_seq.read_oid()?;
if oid != OID_EC_PUBLIC_KEY {
return None;
}
let curve_oid = algo_seq.read_oid()?;
let curve = EcCurve::from_oid(curve_oid)?;
let pk_bits = seq.read_bit_string()?;
Some((
Self {
bytes: pk_bits.to_vec(),
},
curve,
))
}
pub fn to_spki_pem(&self, curve: EcCurve) -> String {
pem_encode("PUBLIC KEY", &self.to_spki_der(curve))
}
pub fn from_spki_pem(pem: &str) -> Option<(Self, EcCurve)> {
Self::from_spki_der(&pem_decode("PUBLIC KEY", pem)?)
}
}
impl EcSecretKey {
pub fn to_sec1_der(&self, curve: EcCurve, public_key: Option<&EcPublicKey>) -> Vec<u8> {
let mut inner = DerEncoder::new();
inner.integer_u64(1);
inner.octet_string(&self.bytes);
{
let mut oid_enc = DerEncoder::new();
oid_enc.oid(curve.oid());
let oid_bytes = oid_enc.finish();
inner.context_explicit(0, &oid_bytes);
}
if let Some(pk) = public_key {
let mut bs = DerEncoder::new();
bs.bit_string(&pk.bytes);
let bs_bytes = bs.finish();
inner.context_explicit(1, &bs_bytes);
}
let content = inner.finish();
let mut outer = DerEncoder::new();
outer.sequence(&content);
outer.finish()
}
pub fn from_sec1_der(der: &[u8]) -> Option<(Self, EcCurve, Option<EcPublicKey>)> {
let mut dec = DerDecoder::new(der);
let mut seq = dec.read_sequence()?;
let version = seq.read_integer_u64()?;
if version != 1 {
return None;
}
let sk_bytes = seq.read_octet_string()?;
let mut ctx0 = seq.read_context_explicit(0)?;
let curve_oid = ctx0.read_oid()?;
let curve = EcCurve::from_oid(curve_oid)?;
let pk = if let Some(mut ctx1) = seq.read_context_explicit(1) {
let pk_bits = ctx1.read_bit_string()?;
Some(EcPublicKey {
bytes: pk_bits.to_vec(),
})
} else {
None
};
Some((
Self {
bytes: sk_bytes.to_vec(),
},
curve,
pk,
))
}
pub fn to_pkcs8_der(&self, curve: EcCurve, public_key: Option<&EcPublicKey>) -> Vec<u8> {
let sec1 = self.to_sec1_der(curve, public_key);
let mut algo = DerEncoder::new();
algo.oid(OID_EC_PUBLIC_KEY);
algo.oid(curve.oid());
let algo_bytes = algo.finish();
let mut inner = DerEncoder::new();
inner.integer_u64(0); inner.sequence(&algo_bytes);
inner.octet_string(&sec1);
let content = inner.finish();
let mut outer = DerEncoder::new();
outer.sequence(&content);
outer.finish()
}
pub fn to_sec1_pem(&self, curve: EcCurve, public_key: Option<&EcPublicKey>) -> String {
pem_encode("EC PRIVATE KEY", &self.to_sec1_der(curve, public_key))
}
pub fn to_pkcs8_pem(&self, curve: EcCurve, public_key: Option<&EcPublicKey>) -> String {
pem_encode("PRIVATE KEY", &self.to_pkcs8_der(curve, public_key))
}
}
impl Ed25519PublicKey {
pub fn to_spki_der(&self) -> Vec<u8> {
let mut algo = DerEncoder::new();
algo.oid(OID_ED25519);
let algo_bytes = algo.finish();
let mut inner = DerEncoder::new();
inner.sequence(&algo_bytes);
inner.bit_string(&self.0);
let content = inner.finish();
let mut outer = DerEncoder::new();
outer.sequence(&content);
outer.finish()
}
pub fn from_spki_der(der: &[u8]) -> Option<Self> {
let mut dec = DerDecoder::new(der);
let mut seq = dec.read_sequence()?;
let mut algo_seq = seq.read_sequence()?;
let oid = algo_seq.read_oid()?;
if oid != OID_ED25519 {
return None;
}
let pk_bits = seq.read_bit_string()?;
if pk_bits.len() != 32 {
return None;
}
let mut out = [0u8; 32];
out.copy_from_slice(pk_bits);
Some(Self(out))
}
pub fn to_spki_pem(&self) -> String {
pem_encode("PUBLIC KEY", &self.to_spki_der())
}
pub fn from_spki_pem(pem: &str) -> Option<Self> {
Self::from_spki_der(&pem_decode("PUBLIC KEY", pem)?)
}
}
impl Ed25519SecretKey {
pub fn to_pkcs8_der(&self) -> Vec<u8> {
let mut seed_enc = DerEncoder::new();
seed_enc.octet_string(&self.0);
let seed_der = seed_enc.finish();
let mut algo = DerEncoder::new();
algo.oid(OID_ED25519);
let algo_bytes = algo.finish();
let mut inner = DerEncoder::new();
inner.integer_u64(0); inner.sequence(&algo_bytes);
inner.octet_string(&seed_der);
let content = inner.finish();
let mut outer = DerEncoder::new();
outer.sequence(&content);
outer.finish()
}
pub fn from_pkcs8_der(der: &[u8]) -> Option<Self> {
let mut dec = DerDecoder::new(der);
let mut seq = dec.read_sequence()?;
let version = seq.read_integer_u64()?;
if version != 0 {
return None;
}
let mut algo_seq = seq.read_sequence()?;
let oid = algo_seq.read_oid()?;
if oid != OID_ED25519 {
return None;
}
let pk_octet = seq.read_octet_string()?;
let mut inner = DerDecoder::new(pk_octet);
let seed = inner.read_octet_string()?;
if seed.len() != 32 {
return None;
}
let mut out = [0u8; 32];
out.copy_from_slice(seed);
Some(Self(out))
}
pub fn to_pkcs8_pem(&self) -> String {
pem_encode("PRIVATE KEY", &self.to_pkcs8_der())
}
pub fn from_pkcs8_pem(pem: &str) -> Option<Self> {
Self::from_pkcs8_der(&pem_decode("PRIVATE KEY", pem)?)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ecc::eddsa::ed25519_keygen;
fn rng_fill(buf: &mut [u8]) {
static mut CTR: u64 = 0xdeadbeef;
for b in buf.iter_mut() {
unsafe {
CTR = CTR.wrapping_mul(6364136223846793005).wrapping_add(1);
*b = (CTR >> 33) as u8;
}
}
}
#[test]
fn rsa_pkcs1_roundtrip() {
let (pk, sk) = crate::rsa::rsa::rsa_keygen(1024, &mut rng_fill);
let pk_der = pk.to_pkcs1_der();
let pk_back = RsaPublicKey::from_pkcs1_der(&pk_der).unwrap();
assert_eq!(
pk_back.n.to_be_bytes(pk.n.byte_len()),
pk.n.to_be_bytes(pk.n.byte_len())
);
assert_eq!(
pk_back.e.to_be_bytes(pk.e.byte_len()),
pk.e.to_be_bytes(pk.e.byte_len())
);
let sk_der = sk.to_pkcs1_der();
let sk_back = RsaSecretKey::from_pkcs1_der(&sk_der).unwrap();
assert_eq!(
sk_back.n.to_be_bytes(sk.n.byte_len()),
sk.n.to_be_bytes(sk.n.byte_len())
);
assert_eq!(
sk_back.p.to_be_bytes(sk.p.byte_len()),
sk.p.to_be_bytes(sk.p.byte_len())
);
}
#[test]
fn rsa_spki_roundtrip() {
let (pk, _) = crate::rsa::rsa::rsa_keygen(1024, &mut rng_fill);
let der = pk.to_spki_der();
let pk_back = RsaPublicKey::from_spki_der(&der).unwrap();
assert_eq!(
pk_back.n.to_be_bytes(pk.n.byte_len()),
pk.n.to_be_bytes(pk.n.byte_len())
);
}
#[test]
fn rsa_pem_roundtrip() {
let (pk, sk) = crate::rsa::rsa::rsa_keygen(1024, &mut rng_fill);
let pk_pem = pk.to_pkcs1_pem();
assert!(pk_pem.contains("-----BEGIN RSA PUBLIC KEY-----"));
let pk_back = RsaPublicKey::from_pkcs1_pem(&pk_pem).unwrap();
assert_eq!(
pk_back.n.to_be_bytes(pk.n.byte_len()),
pk.n.to_be_bytes(pk.n.byte_len())
);
let sk_pem = sk.to_pkcs1_pem();
assert!(sk_pem.contains("-----BEGIN RSA PRIVATE KEY-----"));
let sk_back = RsaSecretKey::from_pkcs1_pem(&sk_pem).unwrap();
assert_eq!(
sk_back.p.to_be_bytes(sk.p.byte_len()),
sk.p.to_be_bytes(sk.p.byte_len())
);
}
#[test]
fn ec_spki_roundtrip() {
use crate::ecc::curves::{CryptoRng, Curve, P256};
struct Rng(u64);
impl CryptoRng for Rng {
fn fill_bytes(&mut self, dest: &mut [u8]) {
for b in dest {
self.0 = self.0.wrapping_mul(6364136223846793005).wrapping_add(1);
*b = (self.0 >> 33) as u8;
}
}
}
let (pk, _sk) = P256::keygen(&mut Rng(0xCAFE));
let der = pk.to_spki_der(EcCurve::P256);
let (pk_back, curve) = EcPublicKey::from_spki_der(&der).unwrap();
assert_eq!(curve, EcCurve::P256);
assert_eq!(pk_back.bytes, pk.bytes);
}
#[test]
fn ec_sec1_roundtrip() {
use crate::ecc::curves::{CryptoRng, Curve, P256};
struct Rng(u64);
impl CryptoRng for Rng {
fn fill_bytes(&mut self, dest: &mut [u8]) {
for b in dest {
self.0 = self.0.wrapping_mul(6364136223846793005).wrapping_add(1);
*b = (self.0 >> 33) as u8;
}
}
}
let (pk, sk) = P256::keygen(&mut Rng(0xBEEF));
let der = sk.to_sec1_der(EcCurve::P256, Some(&pk));
let (sk_back, curve, pk_back) = EcSecretKey::from_sec1_der(&der).unwrap();
assert_eq!(curve, EcCurve::P256);
assert_eq!(sk_back.bytes, sk.bytes);
assert_eq!(pk_back.unwrap().bytes, pk.bytes);
}
#[test]
fn ec_pem_roundtrip() {
use crate::ecc::curves::{CryptoRng, Curve, P256};
struct Rng(u64);
impl CryptoRng for Rng {
fn fill_bytes(&mut self, dest: &mut [u8]) {
for b in dest {
self.0 = self.0.wrapping_mul(6364136223846793005).wrapping_add(1);
*b = (self.0 >> 33) as u8;
}
}
}
let (pk, sk) = P256::keygen(&mut Rng(0xFACE));
let pem = pk.to_spki_pem(EcCurve::P256);
assert!(pem.contains("-----BEGIN PUBLIC KEY-----"));
let (pk_back, _) = EcPublicKey::from_spki_pem(&pem).unwrap();
assert_eq!(pk_back.bytes, pk.bytes);
let sk_pem = sk.to_sec1_pem(EcCurve::P256, None);
assert!(sk_pem.contains("-----BEGIN EC PRIVATE KEY-----"));
}
#[test]
fn ed25519_spki_roundtrip() {
let seed = [0x42u8; 32];
let (pk, _sk) = ed25519_keygen(&seed);
let der = pk.to_spki_der();
let pk_back = Ed25519PublicKey::from_spki_der(&der).unwrap();
assert_eq!(pk_back.0, pk.0);
}
#[test]
fn ed25519_pkcs8_roundtrip() {
let seed = [0x42u8; 32];
let (_pk, sk) = ed25519_keygen(&seed);
let der = sk.to_pkcs8_der();
let sk_back = Ed25519SecretKey::from_pkcs8_der(&der).unwrap();
assert_eq!(sk_back.0, sk.0);
}
#[test]
fn ed25519_pem_roundtrip() {
let seed = [0x42u8; 32];
let (pk, sk) = ed25519_keygen(&seed);
let pem = pk.to_spki_pem();
assert!(pem.contains("-----BEGIN PUBLIC KEY-----"));
let pk_back = Ed25519PublicKey::from_spki_pem(&pem).unwrap();
assert_eq!(pk_back.0, pk.0);
let sk_pem = sk.to_pkcs8_pem();
assert!(sk_pem.contains("-----BEGIN PRIVATE KEY-----"));
let sk_back = Ed25519SecretKey::from_pkcs8_pem(&sk_pem).unwrap();
assert_eq!(sk_back.0, sk.0);
}
}