Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update BoringCrypto to FIPS 140-2 certificate 4407. #97

Merged
merged 1 commit into from
May 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,13 @@ jobs:
- name: Install Rust (rustup)
run: rustup update stable --no-self-update && rustup default stable
shell: bash
- name: Install Clang-7
run: sudo apt-get install -y clang-7
- name: Install Clang-12
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
name: Run tests
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ _Warning_: When providing a different version of BoringSSL make sure to use a co

## Building with a FIPS-validated module

Only BoringCrypto module version ae223d6138807a13006342edfeef32e813246b39, as
certified with [certificate
3678](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/3678)
Only BoringCrypto module version 853ca1ea1168dff08011e5d42d94609cc0ca2e27, as certified with
[FIPS 140-2 certificate 4407](https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/4407)
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:

```bash
$ cargo test --features fips fips::is_enabled
```
Expand Down
10 changes: 5 additions & 5 deletions boring-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,14 +241,16 @@ fn verify_fips_clang_version() -> (&'static str, &'static str) {
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");
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 [
("clang-7", "clang++-7"),
("clang-12", "clang++-12"),
("clang", "clang++"),
("cc", "c++"),
] {
Expand Down Expand Up @@ -434,7 +436,6 @@ fn main() {
"aes.h",
"asn1_mac.h",
"asn1t.h",
#[cfg(not(feature = "fips"))]
"blake2.h",
"blowfish.h",
"cast.h",
Expand All @@ -459,7 +460,6 @@ fn main() {
"ripemd.h",
"siphash.h",
"srtp.h",
#[cfg(not(feature = "fips"))]
"trust_token.h",
"x509v3.h",
];
Expand Down
2 changes: 1 addition & 1 deletion boring-sys/deps/boringssl-fips
Submodule boringssl-fips updated 1664 files
9 changes: 0 additions & 9 deletions boring/examples/mk_certs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
#[cfg_attr(feature = "fips", allow(unreachable_code, unused_variables))]
fn mk_ca_signed_cert(
ca_cert: &X509Ref,
ca_privkey: &PKeyRef<Private>,
Expand All @@ -99,15 +98,7 @@ fn mk_ca_signed_cert(
serial.to_asn1_integer()?
};
cert_builder.set_serial_number(&serial_number)?;

#[cfg(not(feature = "fips"))]
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_pubkey(&privkey)?;
let not_before = Asn1Time::days_from_now(0)?;
Expand Down
3 changes: 0 additions & 3 deletions boring/src/pkey.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,8 @@ impl Id {
pub const DH: Id = Id(ffi::EVP_PKEY_DH);
pub const EC: Id = Id(ffi::EVP_PKEY_EC);
pub const ED25519: Id = Id(ffi::EVP_PKEY_ED25519);
#[cfg(not(feature = "fips"))]
pub const ED448: Id = Id(ffi::EVP_PKEY_ED448);
pub const X25519: Id = Id(ffi::EVP_PKEY_X25519);
#[cfg(not(feature = "fips"))]
pub const X448: Id = Id(ffi::EVP_PKEY_X448);

/// Creates a `Id` from an integer representation.
Expand Down Expand Up @@ -291,7 +289,6 @@ impl<T> fmt::Debug for PKey<T> {
Id::DH => "DH",
Id::EC => "EC",
Id::ED25519 => "Ed25519",
#[cfg(not(feature = "fips"))]
Id::ED448 => "Ed448",
_ => "unknown",
};
Expand Down
4 changes: 0 additions & 4 deletions boring/src/ssl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,10 +486,8 @@ impl ExtensionType {
Self(ffi::TLSEXT_TYPE_application_layer_protocol_negotiation 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);
#[cfg(not(feature = "fips"))]
pub const QUIC_TRANSPORT_PARAMETERS_LEGACY: Self =
Self(ffi::TLSEXT_TYPE_quic_transport_parameters_legacy as u16);
#[cfg(not(feature = "fips"))]
pub const QUIC_TRANSPORT_PARAMETERS_STANDARD: Self =
Self(ffi::TLSEXT_TYPE_quic_transport_parameters_standard as u16);
pub const CERT_COMPRESSION: Self = Self(ffi::TLSEXT_TYPE_cert_compression as u16);
Expand All @@ -506,9 +504,7 @@ impl ExtensionType {
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 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);
#[cfg(not(feature = "fips"))]
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 NEXT_PROTO_NEG: Self = Self(ffi::TLSEXT_TYPE_next_proto_neg as u16);
Expand Down
9 changes: 1 addition & 8 deletions boring/src/ssl/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,19 +448,12 @@ fn test_alpn_server_select_none_fatal() {
ssl::select_next_proto(b"\x08http/1.1\x08spdy/3.1", client)
.ok_or(ssl::AlpnError::ALERT_FATAL)
});
#[cfg(not(feature = "fips"))]
server.should_error();
let server = server.build();

let mut client = server.client();
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]
Expand Down
27 changes: 12 additions & 15 deletions boring/src/x509/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ impl X509StoreContextRef {
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.
///
/// This corresponds to [`X509_STORE_CTX_get0_chain`].
Expand Down Expand Up @@ -230,14 +229,12 @@ impl X509Builder {

/// Sets the notAfter constraint on the certificate.
pub fn set_not_after(&mut self, not_after: &Asn1TimeRef) -> Result<(), ErrorStack> {
// TODO: once FIPS supports `set1_notAfter`, use that instead
unsafe { cvt(X509_set_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) }
unsafe { cvt(X509_set1_notAfter(self.0.as_ptr(), not_after.as_ptr())).map(|_| ()) }
}

/// Sets the notBefore constraint on the certificate.
pub fn set_not_before(&mut self, not_before: &Asn1TimeRef) -> Result<(), ErrorStack> {
// TODO: once FIPS supports `set1_notBefore`, use that instead
unsafe { cvt(X509_set_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) }
unsafe { cvt(X509_set1_notBefore(self.0.as_ptr(), not_before.as_ptr())).map(|_| ()) }
}

/// Sets the version of the certificate.
Expand Down Expand Up @@ -496,18 +493,18 @@ impl X509Ref {
/// Returns the certificate's Not After validity period.
pub fn not_after(&self) -> &Asn1TimeRef {
unsafe {
let date = X509_get0_notAfter(self.as_ptr());
let date = X509_getm_notAfter(self.as_ptr());
assert!(!date.is_null());
Asn1TimeRef::from_ptr(date as *mut _)
Asn1TimeRef::from_ptr(date)
}
}

/// Returns the certificate's Not Before validity period.
pub fn not_before(&self) -> &Asn1TimeRef {
unsafe {
let date = X509_get0_notBefore(self.as_ptr());
let date = X509_getm_notBefore(self.as_ptr());
assert!(!date.is_null());
Asn1TimeRef::from_ptr(date as *mut _)
Asn1TimeRef::from_ptr(date)
}
}

Expand Down Expand Up @@ -1163,7 +1160,6 @@ impl X509ReqRef {
ffi::i2d_X509_REQ
}

#[cfg(not(feature = "fips"))]
/// Returns the numerical value of the version field of the certificate request.
///
/// This corresponds to [`X509_REQ_get_version`]
Expand All @@ -1173,7 +1169,6 @@ impl X509ReqRef {
unsafe { X509_REQ_get_version(self.as_ptr()) as i32 }
}

#[cfg(not(feature = "fips"))]
/// Returns the subject name of the certificate request.
///
/// This corresponds to [`X509_REQ_get_subject_name`]
Expand Down Expand Up @@ -1406,12 +1401,14 @@ impl Stackable for X509Object {
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::{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)]
unsafe fn X509_OBJECT_free(x: *mut ffi::X509_OBJECT) {
Expand Down