Update BoringCrypto to FIPS 140-2 certificate 4407.
Signed-off-by: Piotr Sikora <piotr@aviatrix.com>
This commit is contained in:
parent
4ce9c50b63
commit
902e7d0c92
|
|
@ -187,7 +187,13 @@ jobs:
|
||||||
- name: Install Rust (rustup)
|
- name: Install Rust (rustup)
|
||||||
run: rustup update stable --no-self-update && rustup default stable
|
run: rustup update stable --no-self-update && rustup default stable
|
||||||
shell: bash
|
shell: bash
|
||||||
- name: Install Clang-7
|
- name: Install Clang-12
|
||||||
run: sudo apt-get install -y clang-7
|
uses: KyleMayes/install-llvm-action@v1
|
||||||
|
with:
|
||||||
|
version: "12.0.0"
|
||||||
|
directory: ${{ runner.temp }}/llvm
|
||||||
|
- name: Add clang++-12 link
|
||||||
|
working-directory: ${{ runner.temp }}/llvm/bin
|
||||||
|
run: ln -s clang clang++-12
|
||||||
- run: cargo test --features fips
|
- run: cargo test --features fips
|
||||||
name: Run tests
|
name: Run tests
|
||||||
|
|
|
||||||
|
|
@ -24,12 +24,12 @@ _Warning_: When providing a different version of BoringSSL make sure to use a co
|
||||||
|
|
||||||
## Building with a FIPS-validated module
|
## Building with a FIPS-validated module
|
||||||
|
|
||||||
Only BoringCrypto module version ae223d6138807a13006342edfeef32e813246b39, as
|
Only BoringCrypto module version 853ca1ea1168dff08011e5d42d94609cc0ca2e27, as certified with
|
||||||
certified with [certificate
|
[FIPS 140-2 certificate 4407](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4407)
|
||||||
3678](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/3678)
|
|
||||||
is supported by this crate. Support is enabled by this crate's `fips` feature.
|
is supported by this crate. Support is enabled by this crate's `fips` feature.
|
||||||
|
|
||||||
`boring-sys` comes with a test that FIPS is enabled/disabled depending on the feature flag. You can run it as follows:
|
`boring-sys` comes with a test that FIPS is enabled/disabled depending on the feature flag. You can run it as follows:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ cargo test --features fips fips::is_enabled
|
$ cargo test --features fips fips::is_enabled
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -241,14 +241,16 @@ fn verify_fips_clang_version() -> (&'static str, &'static str) {
|
||||||
return String::new();
|
return String::new();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
assert!(output.status.success());
|
if !output.status.success() {
|
||||||
|
return String::new();
|
||||||
|
}
|
||||||
let output = std::str::from_utf8(&output.stdout).expect("invalid utf8 output");
|
let output = std::str::from_utf8(&output.stdout).expect("invalid utf8 output");
|
||||||
output.lines().next().expect("empty output").to_string()
|
output.lines().next().expect("empty output").to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
const REQUIRED_CLANG_VERSION: &str = "7.0.1";
|
const REQUIRED_CLANG_VERSION: &str = "12.0.0";
|
||||||
for (cc, cxx) in [
|
for (cc, cxx) in [
|
||||||
("clang-7", "clang++-7"),
|
("clang-12", "clang++-12"),
|
||||||
("clang", "clang++"),
|
("clang", "clang++"),
|
||||||
("cc", "c++"),
|
("cc", "c++"),
|
||||||
] {
|
] {
|
||||||
|
|
@ -434,7 +436,6 @@ fn main() {
|
||||||
"aes.h",
|
"aes.h",
|
||||||
"asn1_mac.h",
|
"asn1_mac.h",
|
||||||
"asn1t.h",
|
"asn1t.h",
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
"blake2.h",
|
"blake2.h",
|
||||||
"blowfish.h",
|
"blowfish.h",
|
||||||
"cast.h",
|
"cast.h",
|
||||||
|
|
@ -459,7 +460,6 @@ fn main() {
|
||||||
"ripemd.h",
|
"ripemd.h",
|
||||||
"siphash.h",
|
"siphash.h",
|
||||||
"srtp.h",
|
"srtp.h",
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
"trust_token.h",
|
"trust_token.h",
|
||||||
"x509v3.h",
|
"x509v3.h",
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit ae223d6138807a13006342edfeef32e813246b39
|
Subproject commit 853ca1ea1168dff08011e5d42d94609cc0ca2e27
|
||||||
|
|
@ -81,7 +81,6 @@ fn mk_request(privkey: &PKey<Private>) -> Result<X509Req, ErrorStack> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make a certificate and private key signed by the given CA cert and private key
|
/// Make a certificate and private key signed by the given CA cert and private key
|
||||||
#[cfg_attr(feature = "fips", allow(unreachable_code, unused_variables))]
|
|
||||||
fn mk_ca_signed_cert(
|
fn mk_ca_signed_cert(
|
||||||
ca_cert: &X509Ref,
|
ca_cert: &X509Ref,
|
||||||
ca_privkey: &PKeyRef<Private>,
|
ca_privkey: &PKeyRef<Private>,
|
||||||
|
|
@ -99,15 +98,7 @@ fn mk_ca_signed_cert(
|
||||||
serial.to_asn1_integer()?
|
serial.to_asn1_integer()?
|
||||||
};
|
};
|
||||||
cert_builder.set_serial_number(&serial_number)?;
|
cert_builder.set_serial_number(&serial_number)?;
|
||||||
|
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
cert_builder.set_subject_name(req.subject_name())?;
|
cert_builder.set_subject_name(req.subject_name())?;
|
||||||
#[cfg(feature = "fips")]
|
|
||||||
{
|
|
||||||
eprintln!("mk_certs not supported with FIPS module");
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
cert_builder.set_issuer_name(ca_cert.subject_name())?;
|
cert_builder.set_issuer_name(ca_cert.subject_name())?;
|
||||||
cert_builder.set_pubkey(&privkey)?;
|
cert_builder.set_pubkey(&privkey)?;
|
||||||
let not_before = Asn1Time::days_from_now(0)?;
|
let not_before = Asn1Time::days_from_now(0)?;
|
||||||
|
|
|
||||||
|
|
@ -76,10 +76,8 @@ impl Id {
|
||||||
pub const DH: Id = Id(ffi::EVP_PKEY_DH);
|
pub const DH: Id = Id(ffi::EVP_PKEY_DH);
|
||||||
pub const EC: Id = Id(ffi::EVP_PKEY_EC);
|
pub const EC: Id = Id(ffi::EVP_PKEY_EC);
|
||||||
pub const ED25519: Id = Id(ffi::EVP_PKEY_ED25519);
|
pub const ED25519: Id = Id(ffi::EVP_PKEY_ED25519);
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
pub const ED448: Id = Id(ffi::EVP_PKEY_ED448);
|
pub const ED448: Id = Id(ffi::EVP_PKEY_ED448);
|
||||||
pub const X25519: Id = Id(ffi::EVP_PKEY_X25519);
|
pub const X25519: Id = Id(ffi::EVP_PKEY_X25519);
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
pub const X448: Id = Id(ffi::EVP_PKEY_X448);
|
pub const X448: Id = Id(ffi::EVP_PKEY_X448);
|
||||||
|
|
||||||
/// Creates a `Id` from an integer representation.
|
/// Creates a `Id` from an integer representation.
|
||||||
|
|
@ -291,7 +289,6 @@ impl<T> fmt::Debug for PKey<T> {
|
||||||
Id::DH => "DH",
|
Id::DH => "DH",
|
||||||
Id::EC => "EC",
|
Id::EC => "EC",
|
||||||
Id::ED25519 => "Ed25519",
|
Id::ED25519 => "Ed25519",
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
Id::ED448 => "Ed448",
|
Id::ED448 => "Ed448",
|
||||||
_ => "unknown",
|
_ => "unknown",
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -486,10 +486,8 @@ impl ExtensionType {
|
||||||
Self(ffi::TLSEXT_TYPE_application_layer_protocol_negotiation as u16);
|
Self(ffi::TLSEXT_TYPE_application_layer_protocol_negotiation as u16);
|
||||||
pub const PADDING: Self = Self(ffi::TLSEXT_TYPE_padding as u16);
|
pub const PADDING: Self = Self(ffi::TLSEXT_TYPE_padding as u16);
|
||||||
pub const EXTENDED_MASTER_SECRET: Self = Self(ffi::TLSEXT_TYPE_extended_master_secret as u16);
|
pub const EXTENDED_MASTER_SECRET: Self = Self(ffi::TLSEXT_TYPE_extended_master_secret as u16);
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
pub const QUIC_TRANSPORT_PARAMETERS_LEGACY: Self =
|
pub const QUIC_TRANSPORT_PARAMETERS_LEGACY: Self =
|
||||||
Self(ffi::TLSEXT_TYPE_quic_transport_parameters_legacy as u16);
|
Self(ffi::TLSEXT_TYPE_quic_transport_parameters_legacy as u16);
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
pub const QUIC_TRANSPORT_PARAMETERS_STANDARD: Self =
|
pub const QUIC_TRANSPORT_PARAMETERS_STANDARD: Self =
|
||||||
Self(ffi::TLSEXT_TYPE_quic_transport_parameters_standard as u16);
|
Self(ffi::TLSEXT_TYPE_quic_transport_parameters_standard as u16);
|
||||||
pub const CERT_COMPRESSION: Self = Self(ffi::TLSEXT_TYPE_cert_compression as u16);
|
pub const CERT_COMPRESSION: Self = Self(ffi::TLSEXT_TYPE_cert_compression as u16);
|
||||||
|
|
@ -506,9 +504,7 @@ impl ExtensionType {
|
||||||
pub const KEY_SHARE: Self = Self(ffi::TLSEXT_TYPE_key_share as u16);
|
pub const KEY_SHARE: Self = Self(ffi::TLSEXT_TYPE_key_share as u16);
|
||||||
pub const RENEGOTIATE: Self = Self(ffi::TLSEXT_TYPE_renegotiate as u16);
|
pub const RENEGOTIATE: Self = Self(ffi::TLSEXT_TYPE_renegotiate as u16);
|
||||||
pub const DELEGATED_CREDENTIAL: Self = Self(ffi::TLSEXT_TYPE_delegated_credential as u16);
|
pub const DELEGATED_CREDENTIAL: Self = Self(ffi::TLSEXT_TYPE_delegated_credential as u16);
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
pub const APPLICATION_SETTINGS: Self = Self(ffi::TLSEXT_TYPE_application_settings as u16);
|
pub const APPLICATION_SETTINGS: Self = Self(ffi::TLSEXT_TYPE_application_settings as u16);
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
pub const ENCRYPTED_CLIENT_HELLO: Self = Self(ffi::TLSEXT_TYPE_encrypted_client_hello as u16);
|
pub const ENCRYPTED_CLIENT_HELLO: Self = Self(ffi::TLSEXT_TYPE_encrypted_client_hello as u16);
|
||||||
pub const CERTIFICATE_TIMESTAMP: Self = Self(ffi::TLSEXT_TYPE_certificate_timestamp as u16);
|
pub const CERTIFICATE_TIMESTAMP: Self = Self(ffi::TLSEXT_TYPE_certificate_timestamp as u16);
|
||||||
pub const NEXT_PROTO_NEG: Self = Self(ffi::TLSEXT_TYPE_next_proto_neg as u16);
|
pub const NEXT_PROTO_NEG: Self = Self(ffi::TLSEXT_TYPE_next_proto_neg as u16);
|
||||||
|
|
|
||||||
|
|
@ -448,20 +448,13 @@ fn test_alpn_server_select_none_fatal() {
|
||||||
ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client)
|
ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client)
|
||||||
.ok_or(ssl::AlpnError::ALERT_FATAL)
|
.ok_or(ssl::AlpnError::ALERT_FATAL)
|
||||||
});
|
});
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
server.should_error();
|
server.should_error();
|
||||||
let server = server.build();
|
let server = server.build();
|
||||||
|
|
||||||
let mut client = server.client();
|
let mut client = server.client();
|
||||||
client.ctx().set_alpn_protos(b"\x06http/2").unwrap();
|
client.ctx().set_alpn_protos(b"\x06http/2").unwrap();
|
||||||
|
|
||||||
if cfg!(feature = "fips") {
|
|
||||||
let s = client.connect();
|
|
||||||
assert_eq!(None, s.ssl().selected_alpn_protocol());
|
|
||||||
} else {
|
|
||||||
client.connect_err();
|
client.connect_err();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_alpn_server_select_none() {
|
fn test_alpn_server_select_none() {
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,6 @@ impl X509StoreContextRef {
|
||||||
unsafe { ffi::X509_STORE_CTX_get_error_depth(self.as_ptr()) as u32 }
|
unsafe { ffi::X509_STORE_CTX_get_error_depth(self.as_ptr()) as u32 }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
/// Returns a reference to a complete valid `X509` certificate chain.
|
/// Returns a reference to a complete valid `X509` certificate chain.
|
||||||
///
|
///
|
||||||
/// This corresponds to [`X509_STORE_CTX_get0_chain`].
|
/// This corresponds to [`X509_STORE_CTX_get0_chain`].
|
||||||
|
|
@ -230,14 +229,12 @@ impl X509Builder {
|
||||||
|
|
||||||
/// Sets the notAfter constraint on the certificate.
|
/// Sets the notAfter constraint on the certificate.
|
||||||
pub fn set_not_after(&mut self, not_after: &Asn1TimeRef) -> Result<(), ErrorStack> {
|
pub fn set_not_after(&mut self, not_after: &Asn1TimeRef) -> Result<(), ErrorStack> {
|
||||||
// TODO: once FIPS supports `set1_notAfter`, use that instead
|
unsafe { cvt(X509_set1_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) }
|
||||||
unsafe { cvt(X509_set_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the notBefore constraint on the certificate.
|
/// Sets the notBefore constraint on the certificate.
|
||||||
pub fn set_not_before(&mut self, not_before: &Asn1TimeRef) -> Result<(), ErrorStack> {
|
pub fn set_not_before(&mut self, not_before: &Asn1TimeRef) -> Result<(), ErrorStack> {
|
||||||
// TODO: once FIPS supports `set1_notBefore`, use that instead
|
unsafe { cvt(X509_set1_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) }
|
||||||
unsafe { cvt(X509_set_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the version of the certificate.
|
/// Sets the version of the certificate.
|
||||||
|
|
@ -496,18 +493,18 @@ impl X509Ref {
|
||||||
/// Returns the certificate's Not After validity period.
|
/// Returns the certificate's Not After validity period.
|
||||||
pub fn not_after(&self) -> &Asn1TimeRef {
|
pub fn not_after(&self) -> &Asn1TimeRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
let date = X509_get0_notAfter(self.as_ptr());
|
let date = X509_getm_notAfter(self.as_ptr());
|
||||||
assert!(!date.is_null());
|
assert!(!date.is_null());
|
||||||
Asn1TimeRef::from_ptr(date as *mut _)
|
Asn1TimeRef::from_ptr(date)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the certificate's Not Before validity period.
|
/// Returns the certificate's Not Before validity period.
|
||||||
pub fn not_before(&self) -> &Asn1TimeRef {
|
pub fn not_before(&self) -> &Asn1TimeRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
let date = X509_get0_notBefore(self.as_ptr());
|
let date = X509_getm_notBefore(self.as_ptr());
|
||||||
assert!(!date.is_null());
|
assert!(!date.is_null());
|
||||||
Asn1TimeRef::from_ptr(date as *mut _)
|
Asn1TimeRef::from_ptr(date)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1163,7 +1160,6 @@ impl X509ReqRef {
|
||||||
ffi::i2d_X509_REQ
|
ffi::i2d_X509_REQ
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
/// Returns the numerical value of the version field of the certificate request.
|
/// Returns the numerical value of the version field of the certificate request.
|
||||||
///
|
///
|
||||||
/// This corresponds to [`X509_REQ_get_version`]
|
/// This corresponds to [`X509_REQ_get_version`]
|
||||||
|
|
@ -1173,7 +1169,6 @@ impl X509ReqRef {
|
||||||
unsafe { X509_REQ_get_version(self.as_ptr()) as i32 }
|
unsafe { X509_REQ_get_version(self.as_ptr()) as i32 }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
/// Returns the subject name of the certificate request.
|
/// Returns the subject name of the certificate request.
|
||||||
///
|
///
|
||||||
/// This corresponds to [`X509_REQ_get_subject_name`]
|
/// This corresponds to [`X509_REQ_get_subject_name`]
|
||||||
|
|
@ -1406,12 +1401,14 @@ impl Stackable for X509Object {
|
||||||
type StackType = ffi::stack_st_X509_OBJECT;
|
type StackType = ffi::stack_st_X509_OBJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::ffi::{X509_get0_notAfter, X509_get0_notBefore, X509_get0_signature, X509_up_ref};
|
use crate::ffi::{X509_get0_signature, X509_getm_notAfter, X509_getm_notBefore, X509_up_ref};
|
||||||
|
|
||||||
|
use crate::ffi::{
|
||||||
|
ASN1_STRING_get0_data, X509_ALGOR_get0, X509_REQ_get_subject_name, X509_REQ_get_version,
|
||||||
|
X509_STORE_CTX_get0_chain, X509_set1_notAfter, X509_set1_notBefore,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::ffi::X509_OBJECT_get0_X509;
|
use crate::ffi::X509_OBJECT_get0_X509;
|
||||||
use crate::ffi::{ASN1_STRING_get0_data, X509_ALGOR_get0, X509_set_notAfter, X509_set_notBefore};
|
|
||||||
#[cfg(not(feature = "fips"))]
|
|
||||||
use crate::ffi::{X509_REQ_get_subject_name, X509_REQ_get_version, X509_STORE_CTX_get0_chain};
|
|
||||||
|
|
||||||
#[allow(bad_style)]
|
#[allow(bad_style)]
|
||||||
unsafe fn X509_OBJECT_free(x: *mut ffi::X509_OBJECT) {
|
unsafe fn X509_OBJECT_free(x: *mut ffi::X509_OBJECT) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue