Skip to content

Commit

Permalink
cleanup Signer constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
bluejekyll committed May 6, 2017
1 parent d0ed105 commit acf106d
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 93 deletions.
12 changes: 6 additions & 6 deletions client/src/client/secure_client_handle.rs
Expand Up @@ -12,6 +12,7 @@ use std::rc::Rc;

use futures::*;

use chrono::Duration;
use client::ClientHandle;
use error::*;
use op::{Message, OpCode, Query};
Expand Down Expand Up @@ -702,12 +703,11 @@ fn verify_rrset_with_dnskey(dnskey: &DNSKEY, sig: &SIG, rrset: &Rrset) -> Client
}
let pkey = pkey.unwrap();

let signer: Signer = Signer::dnssec_verifier(dnskey.clone(),
*dnskey.algorithm(),
pkey,
sig.signer_name().clone(),
dnskey.zone_key(),
false);
let signer: Signer = Signer::dnssec(dnskey.clone(),
pkey,
sig.signer_name().clone(),
Duration::zero(),
false);

signer
.hash_rrset_with_sig(&rrset.name, rrset.record_class, sig, &rrset.records)
Expand Down
69 changes: 44 additions & 25 deletions client/src/rr/dnssec/keypair.rs
Expand Up @@ -28,7 +28,7 @@ use untrusted::Input;
use error::*;
use rr::Name;
use rr::dnssec::{Algorithm, DigestType};
use rr::rdata::{DNSKEY, DS};
use rr::rdata::{DNSKEY, DS, KEY};

/// A public and private key pair, the private portion is not required.
///
Expand Down Expand Up @@ -95,7 +95,7 @@ impl KeyPair {
pub fn from_public_bytes(public_key: &[u8], algorithm: Algorithm) -> DnsSecResult<Self> {
match algorithm {
#[cfg(feature = "openssl")]
Algorithm::RSASHA1 |
Algorithm::RSASHA1 |
Algorithm::RSASHA1NSEC3SHA1 |
Algorithm::RSASHA256 |
Algorithm::RSASHA512 => {
Expand Down Expand Up @@ -150,7 +150,7 @@ impl KeyPair {
.and_then(|rsa| Self::from_rsa(rsa))
}
#[cfg(feature = "openssl")]
Algorithm::ECDSAP256SHA256 => {
Algorithm::ECDSAP256SHA256 => {
// RFC 6605 ECDSA for DNSSEC April 2012
//
// 4. DNSKEY and RRSIG Resource Records for ECDSA
Expand Down Expand Up @@ -191,7 +191,7 @@ impl KeyPair {
.map_err(|e| e.into())
}
#[cfg(feature = "openssl")]
Algorithm::ECDSAP384SHA384 => {
Algorithm::ECDSAP384SHA384 => {
// see above Algorithm::ECDSAP256SHA256 for reference
EcGroup::from_curve_name(nid::SECP384R1)
.and_then(|group| BigNumContext::new().map(|ctx| (group, ctx)))
Expand All @@ -203,7 +203,7 @@ impl KeyPair {
.map_err(|e| e.into())
}
#[cfg(feature = "ring")]
Algorithm::ED25519 => {
Algorithm::ED25519 => {
// Internet-Draft EdDSA for DNSSEC December 2016
//
// An Ed25519 public key consists of a 32-octet value, which is encoded
Expand Down Expand Up @@ -245,7 +245,7 @@ impl KeyPair {
match *self {
// see from_vec() RSA sections for reference
#[cfg(feature = "openssl")]
KeyPair::RSA(ref pkey) => {
KeyPair::RSA(ref pkey) => {
let mut bytes: Vec<u8> = Vec::new();
// TODO: make these expects a try! and Err()
let rsa: OpenSslRsa = pkey.rsa()
Expand Down Expand Up @@ -276,7 +276,7 @@ impl KeyPair {
}
// see from_vec() ECDSA sections for reference
#[cfg(feature = "openssl")]
KeyPair::EC(ref pkey) => {
KeyPair::EC(ref pkey) => {
// TODO: make these expects a try! and Err()
let ec_key: EcKey = pkey.ec_key()
.expect("pkey should have been initialized with EC");
Expand All @@ -295,7 +295,7 @@ impl KeyPair {
})
}
#[cfg(feature = "ring")]
KeyPair::ED25519(ref ed_key) => {
KeyPair::ED25519(ref ed_key) => {
// this is "little endian" encoded bytes... we need to special case
// serialzation/deserialization for endianess. why, Intel, why...
let mut pub_key = ed_key.public_key.to_vec();
Expand Down Expand Up @@ -379,18 +379,37 @@ impl KeyPair {
///
/// # Arguments
///
/// * `name` - name of the entity associated with this DNSKEY
/// * `ttl` - the time to live for this DNSKEY
/// * `algorithm` - algorithm of the DNSKEY
///
/// # Return
///
/// the DNSKEY record data
// pub fn to_dnskey(&self, name: Name, ttl: u32, algorithm: Algorithm) -> DnsSecResult<DNSKEY> {
pub fn to_dnskey(&self, algorithm: Algorithm) -> DnsSecResult<DNSKEY> {
self.to_public_bytes()
.map(|bytes| DNSKEY::new(true, true, false, algorithm, bytes))
}

/// Convert this keypair into a KEY record type for usage with SIG0
///
/// # Arguments
///
/// * `algorithm` - algorithm of the KEY
///
/// # Return
///
/// the KEY record data
pub fn to_sig0key(&self, algorithm: Algorithm) -> DnsSecResult<KEY> {
self.to_public_bytes()
.map(|bytes| {
KEY::new(Default::default(),
Default::default(),
Default::default(),
Default::default(),
algorithm,
bytes)
})
}

/// Creates a DS record for this KeyPair associated to the given name
///
/// # Arguments
Expand Down Expand Up @@ -427,23 +446,23 @@ impl KeyPair {
pub fn sign(&self, algorithm: Algorithm, message: &[u8]) -> DnsSecResult<Vec<u8>> {
match *self {
#[cfg(feature = "openssl")]
KeyPair::RSA(ref pkey) |
KeyPair::RSA(ref pkey) |
KeyPair::EC(ref pkey) => {
let digest_type = try!(DigestType::from(algorithm).to_openssl_digest());
let mut signer = Signer::new(digest_type, &pkey).unwrap();
try!(signer.update(&message));
signer.finish().map_err(|e| e.into())
}
#[cfg(feature = "ring")]
KeyPair::ED25519(ref ed_key) => {
KeyPair::ED25519(ref ed_key) => {
Ed25519KeyPair::from_bytes(&ed_key.private_key, &ed_key.public_key)
.map_err(|_| {
DnsSecErrorKind::Message("something is wrong with the keys").into()
})
.map(|ed_key| ed_key.sign(message).as_slice().to_vec())
}
#[cfg(not(any(feature = "openssl", feature = "ring")))]
_ => Err(DnsSecErrorKind::Message("openssl nor ring feature(s) not enabled").into()),
_ => Err(DnsSecErrorKind::Message("openssl nor ring feature(s) not enabled").into()),
}
}

Expand All @@ -466,7 +485,7 @@ impl KeyPair {
-> DnsSecResult<()> {
match *self {
#[cfg(feature = "openssl")]
KeyPair::RSA(ref pkey) |
KeyPair::RSA(ref pkey) |
KeyPair::EC(ref pkey) => {
let digest_type = try!(DigestType::from(algorithm).to_openssl_digest());
let mut verifier = Verifier::new(digest_type, &pkey).unwrap();
Expand All @@ -481,7 +500,7 @@ impl KeyPair {
})
}
#[cfg(feature = "ring")]
KeyPair::ED25519(ref ed_key) => {
KeyPair::ED25519(ref ed_key) => {
let public_key = Input::from(&ed_key.public_key);
let message = Input::from(message);
let signature = Input::from(signature);
Expand All @@ -501,10 +520,10 @@ impl KeyPair {
pub fn to_private_bytes(&self) -> DnsSecResult<Vec<u8>> {
match *self {
#[cfg(feature = "openssl")]
KeyPair::RSA(ref pkey) |
KeyPair::RSA(ref pkey) |
KeyPair::EC(ref pkey) => pkey.private_key_to_pem().map_err(|e| e.into()),
#[cfg(feature = "ring")]
KeyPair::ED25519(ref ed_key) => {
KeyPair::ED25519(ref ed_key) => {
let mut vec = Vec::with_capacity(ed_key.private_key.len() +
ed_key.public_key.len());

Expand All @@ -524,21 +543,21 @@ impl KeyPair {
pub fn from_private_bytes(algorithm: Algorithm, bytes: &[u8]) -> DnsSecResult<Self> {
match algorithm {
#[cfg(feature = "openssl")]
Algorithm::RSASHA1 |
Algorithm::RSASHA1 |
Algorithm::RSASHA1NSEC3SHA1 |
Algorithm::RSASHA256 |
Algorithm::RSASHA512 => {
let rsa = try!(OpenSslRsa::private_key_from_pem(bytes));
KeyPair::from_rsa(rsa)
}
#[cfg(feature = "openssl")]
Algorithm::ECDSAP256SHA256 |
Algorithm::ECDSAP256SHA256 |
Algorithm::ECDSAP384SHA384 => {
let ec = try!(EcKey::private_key_from_pem(bytes));
KeyPair::from_ec_key(ec)
}
#[cfg(feature = "ring")]
Algorithm::ED25519 => {
Algorithm::ED25519 => {
let mut private_key = [0u8; 32];
let mut public_key = [0u8; 32];

Expand Down Expand Up @@ -566,7 +585,7 @@ impl KeyPair {
pub fn generate(algorithm: Algorithm) -> DnsSecResult<Self> {
match algorithm {
#[cfg(feature = "openssl")]
Algorithm::RSASHA1 |
Algorithm::RSASHA1 |
Algorithm::RSASHA1NSEC3SHA1 |
Algorithm::RSASHA256 |
Algorithm::RSASHA512 => {
Expand All @@ -576,21 +595,21 @@ impl KeyPair {
.and_then(|rsa| KeyPair::from_rsa(rsa))
}
#[cfg(feature = "openssl")]
Algorithm::ECDSAP256SHA256 => {
Algorithm::ECDSAP256SHA256 => {
EcGroup::from_curve_name(nid::SECP256K1)
.and_then(|group| EcKey::generate(&group))
.map_err(|e| e.into())
.and_then(|ec_key| KeyPair::from_ec_key(ec_key))
}
#[cfg(feature = "openssl")]
Algorithm::ECDSAP384SHA384 => {
Algorithm::ECDSAP384SHA384 => {
EcGroup::from_curve_name(nid::SECP384R1)
.and_then(|group| EcKey::generate(&group))
.map_err(|e| e.into())
.and_then(|ec_key| KeyPair::from_ec_key(ec_key))
}
#[cfg(feature = "ring")]
Algorithm::ED25519 => {
Algorithm::ED25519 => {
let rng = rand::SystemRandom::new();
Ed25519KeyPair::generate_serializable(&rng)
.map_err(|e| e.into())
Expand Down
51 changes: 35 additions & 16 deletions client/src/rr/dnssec/signer.rs
Expand Up @@ -32,6 +32,8 @@ use serialize::binary::{BinEncoder, BinSerializable, EncodeMode};

/// Use for performing signing and validation of DNSSec based components.
///
/// TODO: warning this struct and it's impl are under high volatility, expect breaking changes
///
/// [RFC 4035](https://tools.ietf.org/html/rfc4035), DNSSEC Protocol Modifications, March 2005
///
/// ```text
Expand Down Expand Up @@ -248,39 +250,56 @@ pub struct Signer;
#[cfg(any(feature = "openssl", feature = "ring"))]
impl Signer {
/// Version of Signer for verifying RRSIGs and SIG0 records.
pub fn dnssec_verifier(key_rdata: DNSKEY,
algorithm: Algorithm,
key: KeyPair,
signer_name: Name,
is_zone_signing_key: bool,
is_zone_update_auth: bool)
-> Self {
///
/// # Arguments
///
/// * `key_rdata` - the DNSKEY and public key material
/// * `key` - the private key for signing, unless validating, where just the public key is necessary
/// * `signer_name` - name in the zone to which this DNSKEY is bound
/// * `sig_duration` - time period for which this key is valid, 0 when verifying
/// * `is_zone_update_auth` - this key may be used for updating the zone
pub fn dnssec(key_rdata: DNSKEY,
key: KeyPair,
signer_name: Name,
sig_duration: Duration,
is_zone_update_auth: bool)
-> Self {
let algorithm = *key_rdata.algorithm();
let is_zone_signing_key = key_rdata.zone_key();

Signer {
key_rdata: key_rdata.into(),
key: key,
algorithm: algorithm,
signer_name: signer_name,
sig_duration: Duration::zero(),
sig_duration: sig_duration,
is_zone_signing_key: is_zone_signing_key,
is_zone_update_auth: is_zone_update_auth,
}
}

/// Version of Signer for verifying RRSIGs and SIG0 records.
pub fn sig0_verifier(key_rdata: KEY,
algorithm: Algorithm,
key: KeyPair,
signer_name: Name,
is_zone_signing_key: bool,
is_zone_update_auth: bool)
-> Self {
///
/// # Arguments
///
/// * `key_rdata` - the KEY and public key material
/// * `key` - the private key for signing, unless validating, where just the public key is necessary
/// * `signer_name` - name in the zone to which this DNSKEY is bound
/// * `is_zone_update_auth` - this key may be used for updating the zone
pub fn sig0(key_rdata: KEY,
key: KeyPair,
signer_name: Name,
is_zone_update_auth: bool)
-> Self {
let algorithm = *key_rdata.algorithm();

Signer {
key_rdata: key_rdata.into(),
key: key,
algorithm: algorithm,
signer_name: signer_name,
sig_duration: Duration::zero(),
is_zone_signing_key: is_zone_signing_key,
is_zone_signing_key: false,
is_zone_update_auth: is_zone_update_auth,
}
}
Expand Down
1 change: 1 addition & 0 deletions client/src/rr/rdata/key.rs
Expand Up @@ -466,6 +466,7 @@ impl From<UpdateScope> for u16 {
}

#[test]
#[allow(deprecated)]
fn test_update_scope() {
assert_eq!(UpdateScope::default(),
UpdateScope::from(u16::from(UpdateScope::default())));
Expand Down
16 changes: 7 additions & 9 deletions compatibility/tests/sig0_tests.rs
Expand Up @@ -70,21 +70,19 @@ fn create_sig0_ready_client<CC>(conn: CC) -> SyncClient
.expect("failed to read pem");
let rsa = Rsa::private_key_from_pem(&pem_buf).expect("something wrong with key from pem");
let key = KeyPair::from_rsa(rsa).unwrap();
let dns_key = KEY::new(Default::default(),
let sig0key = KEY::new(Default::default(),
KeyUsage::Entity,
Default::default(),
Default::default(),
Algorithm::RSASHA256,
key.to_public_bytes().unwrap());

let signer = Signer::sig0_verifier(dns_key,
Algorithm::RSASHA256,
key,
Name::with_labels(vec!["update".to_string(),
"example".to_string(),
"com".to_string()]),
false,
true);
let signer = Signer::sig0(sig0key,
key,
Name::with_labels(vec!["update".to_string(),
"example".to_string(),
"com".to_string()]),
true);

assert_eq!(signer.calculate_key_tag().unwrap(), 56935_u16);

Expand Down
8 changes: 2 additions & 6 deletions server/src/authority/authority.rs
Expand Up @@ -512,12 +512,8 @@ impl Authority {
}

let pkey = pkey.unwrap();
let signer: Signer = Signer::sig0_verifier(key.clone(),
*key.algorithm(),
pkey,
sig.signer_name().clone(),
false,
true);
let signer: Signer =
Signer::sig0(key.clone(), pkey, sig.signer_name().clone(), true);

signer
.verify_message(update_message, sig.sig(), sig)
Expand Down

0 comments on commit acf106d

Please sign in to comment.