Skip to content

Commit

Permalink
Introduce X509Flags
Browse files Browse the repository at this point in the history
For now it has a single associated constant, X509Flags::TRUSTED_FIRST.
  • Loading branch information
nox committed Jan 3, 2024
1 parent 9445734 commit dfd49f4
Show file tree
Hide file tree
Showing 12 changed files with 314 additions and 3 deletions.
7 changes: 6 additions & 1 deletion boring/src/ssl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3176,7 +3176,7 @@ impl SslRef {
/// This corresponds to [`SSL_get0_param`].
///
/// [`SSL_get0_param`]: https://www.openssl.org/docs/man1.0.2/ssl/SSL_get0_param.html
pub fn param_mut(&mut self) -> &mut X509VerifyParamRef {
pub fn verify_param_mut(&mut self) -> &mut X509VerifyParamRef {
#[cfg(feature = "rpk")]
assert!(
!self.ssl_context().is_rpk(),
Expand All @@ -3186,6 +3186,11 @@ impl SslRef {
unsafe { X509VerifyParamRef::from_ptr_mut(ffi::SSL_get0_param(self.as_ptr())) }
}

/// See [`Self::verify_param_mut`].
pub fn param_mut(&mut self) -> &mut X509VerifyParamRef {
self.verify_param_mut()
}

/// Returns the certificate verification result.
///
/// This corresponds to [`SSL_get_verify_result`].
Expand Down
12 changes: 11 additions & 1 deletion boring/src/x509/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
//! Internet protocols, including SSL/TLS, which is the basis for HTTPS,
//! the secure protocol for browsing the web.

use crate::ffi;
use foreign_types::{ForeignType, ForeignTypeRef};
use libc::{c_int, c_long, c_void};
use std::convert::TryInto;
Expand All @@ -30,12 +29,14 @@ use crate::bio::MemBioSlice;
use crate::conf::ConfRef;
use crate::error::ErrorStack;
use crate::ex_data::Index;
use crate::ffi;
use crate::hash::{DigestBytes, MessageDigest};
use crate::nid::Nid;
use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef, Public};
use crate::ssl::SslRef;
use crate::stack::{Stack, StackRef, Stackable};
use crate::string::OpensslString;
use crate::x509::verify::X509VerifyParamRef;
use crate::{cvt, cvt_n, cvt_p};

pub mod extension;
Expand Down Expand Up @@ -147,6 +148,15 @@ impl X509StoreContextRef {
}
}

/// Returns a mutable reference to the X509 verification configuration.
///
/// This corresponds to [`X509_STORE_CTX_get0_param`].
///
/// [`SSL_get0_param`]: https://www.openssl.org/docs/manmaster/man3/X509_STORE_CTX_get0_param.html
pub fn verify_param_mut(&mut self) -> &mut X509VerifyParamRef {
unsafe { X509VerifyParamRef::from_ptr_mut(ffi::X509_STORE_CTX_get0_param(self.as_ptr())) }
}

/// Verifies the stored certificate.
///
/// Returns `true` if verification succeeds. The `error` method will return the specific
Expand Down
21 changes: 21 additions & 0 deletions boring/src/x509/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
use crate::error::ErrorStack;
use crate::ffi;
use crate::stack::StackRef;
use crate::x509::verify::{X509Flags, X509VerifyParamRef};
use crate::x509::{X509Object, X509};
use crate::{cvt, cvt_p};
use foreign_types::{ForeignType, ForeignTypeRef};
Expand Down Expand Up @@ -91,6 +92,26 @@ impl X509StoreBuilderRef {
pub fn set_default_paths(&mut self) -> Result<(), ErrorStack> {
unsafe { cvt(ffi::X509_STORE_set_default_paths(self.as_ptr())).map(|_| ()) }
}

/// Sets verify flags.
///
/// This corresponds to [`X509_STORE_set_flags`].
///
/// [`X509_STORE_set_flags`]: https://www.openssl.org/docs/manmaster/man3/X509_STORE_set_flags.html
pub fn set_flags(&mut self, flags: X509Flags) {
unsafe {
ffi::X509_STORE_set_flags(self.as_ptr(), flags.bits());
}
}

/// Returns a mutable reference to the X509 verification configuration.
///
/// This corresponds to [`X509_STORE_get0_param`].
///
/// [`SSL_get0_param`]: https://www.openssl.org/docs/manmaster/man3/X509_STORE_get0_param.html
pub fn verify_param_mut(&mut self) -> &mut X509VerifyParamRef {
unsafe { X509VerifyParamRef::from_ptr_mut(ffi::X509_STORE_get0_param(self.as_ptr())) }
}
}

foreign_type_and_impl_send_sync! {
Expand Down
2 changes: 2 additions & 0 deletions boring/src/x509/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use crate::x509::extension::{
use crate::x509::store::X509StoreBuilder;
use crate::x509::{X509Extension, X509Name, X509Req, X509StoreContext, X509};

mod trusted_first;

fn pkey() -> PKey<Private> {
let rsa = Rsa::generate(2048).unwrap();
PKey::from_rsa(rsa).unwrap()
Expand Down
104 changes: 104 additions & 0 deletions boring/src/x509/tests/trusted_first.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//! See https://github.com/google/boringssl/blob/cc696073cffe7978d489297fbdeac4c0030384aa/crypto/x509/x509_test.cc#L3977-L3980

use crate::stack::Stack;
use crate::x509::store::X509StoreBuilder;
use crate::x509::verify::{X509Flags, X509VerifyParamRef};
use crate::x509::{X509Ref, X509StoreContext, X509VerifyError, X509VerifyResult, X509};

#[test]
fn test_verify_cert() {
let root2 = X509::from_pem(include_bytes!("../../../test/root-ca-2.pem")).unwrap();
let root1 = X509::from_pem(include_bytes!("../../../test/root-ca.pem")).unwrap();
let root1_cross = X509::from_pem(include_bytes!("../../../test/root-ca-cross.pem")).unwrap();
let intermediate = X509::from_pem(include_bytes!("../../../test/intermediate-ca.pem")).unwrap();
let leaf = X509::from_pem(include_bytes!("../../../test/cert-with-intermediate.pem")).unwrap();

assert_eq!(Ok(()), verify(&leaf, &[&root1], &[&intermediate], |_| {}));

#[cfg(not(feature = "fips"))]
assert_eq!(
Ok(()),
verify(
&leaf,
&[&root1, &root2],
&[&intermediate, &root1_cross],
|_| {}
)
);

#[cfg(feature = "fips")]
assert_eq!(
Err(X509VerifyError::CERT_HAS_EXPIRED),
verify(
&leaf,
&[&root1, &root2],
&[&intermediate, &root1_cross],
|_| {}
)
);

assert_eq!(
Ok(()),
verify(
&leaf,
&[&root1, &root2],
&[&intermediate, &root1_cross],
|param| param.set_flags(X509Flags::TRUSTED_FIRST),
)
);

assert_eq!(
Err(X509VerifyError::CERT_HAS_EXPIRED),
verify(
&leaf,
&[&root1, &root2],
&[&intermediate, &root1_cross],
|param| param.clear_flags(X509Flags::TRUSTED_FIRST),
)
);

assert_eq!(
Ok(()),
verify(&leaf, &[&root1], &[&intermediate, &root1_cross], |param| {
param.clear_flags(X509Flags::TRUSTED_FIRST)
},)
);
}

fn verify(
cert: &X509Ref,
trusted: &[&X509Ref],
untrusted: &[&X509Ref],
configure: impl FnOnce(&mut X509VerifyParamRef),
) -> X509VerifyResult {
let trusted = {
let mut builder = X509StoreBuilder::new().unwrap();

for cert in trusted {
builder.add_cert((**cert).to_owned()).unwrap();
}

builder.build()
};

let untrusted = {
let mut stack = Stack::new().unwrap();

for cert in untrusted {
stack.push((**cert).to_owned()).unwrap();
}

stack
};

let mut store_ctx = X509StoreContext::new().unwrap();

let _ = store_ctx.init(&trusted, cert, &untrusted, |ctx| {
configure(ctx.verify_param_mut());
ctx.verify_cert().unwrap();

Ok(())
});

store_ctx.verify_result()
}
35 changes: 34 additions & 1 deletion boring/src/x509/verify.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::ffi;
use foreign_types::ForeignTypeRef;
use libc::c_uint;
use libc::{c_uint, c_ulong};
use std::net::IpAddr;

use crate::cvt;
Expand All @@ -24,6 +24,14 @@ bitflags! {
}
}

bitflags! {
/// Flags used to check an `X509` certificate.
#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, Hash)]
pub struct X509Flags: c_ulong {
const TRUSTED_FIRST = ffi::X509_V_FLAG_TRUSTED_FIRST as _;
}
}

foreign_type_and_impl_send_sync! {
type CType = ffi::X509_VERIFY_PARAM;
fn drop = ffi::X509_VERIFY_PARAM_free;
Expand All @@ -33,6 +41,31 @@ foreign_type_and_impl_send_sync! {
}

impl X509VerifyParamRef {
/// Set flags.
///
/// This corresponds to [`X509_VERIFY_PARAM_set_flags`].
///
/// [`X509_VERIFY_PARAM_set_flags`]: https://www.openssl.org/docs/man3.2/man3/X509_VERIFY_PARAM_set_flags.html
pub fn set_flags(&mut self, flags: X509Flags) {
unsafe {
ffi::X509_VERIFY_PARAM_set_flags(self.as_ptr(), flags.bits());
}
}

/// Clear flags.
///
/// Useful to clear out default flags, such as `X509Flags::TRUSTED_FIRST` when the fips feature is off.
///
/// This corresponds to [`X509_VERIFY_PARAM_clear_flags`].
///
/// [`X509_VERIFY_PARAM_set_flags`]: https://www.openssl.org/docs/man3.2/man3/X509_VERIFY_PARAM_set_flags.html
pub fn clear_flags(&mut self, flags: X509Flags) {
unsafe {
ffi::X509_VERIFY_PARAM_clear_flags(self.as_ptr(), flags.bits());
}
}

///
/// Set the host flags.
///
/// This corresponds to [`X509_VERIFY_PARAM_set_hostflags`].
Expand Down
20 changes: 20 additions & 0 deletions boring/test/cert-with-intermediate.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDMzCCAhsCFBEiNxpuknaO7Pw1Yi88UW4aiGo0MA0GCSqGSIb3DQEBCwUAMFIx
CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMS4wLAYDVQQKDCVJbnRl
cm5ldCBXaWRnaXRzIFB0eSBMdGQgSW50ZXJtZWRpYXRlMB4XDTI0MDEwMzE0MjIz
MFoXDTI2MDgxMjE0MjIzMFowWjELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUt
U3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDETMBEGA1UE
AwwKZm9vYmFyLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKj0
JYxEsxejUIX+I5GH0Hg2G0kX/y1H0+Ub3mw2/Ja5BD/yN96/7zMSumXF8uS3Skmp
yiJkbyD01TSRTqjlP7/VCBlyUIChlpLQmrGaijZiT/VCyPXqmcwFzXS5IOTpX1ol
JfW8rA41U1LCIcDUyFf6LtZ/v8rSeKr6TuE6SGV4WRaBm1SrjWBeHVV866CRrtSS
1ieT2asFsAyOZqWhk2fakwwBDFWDhOGIubfO+5aq9cBJbNRlzsgB3UZs3gC0O6Gz
bnZ6oT0TiJMeTsXXjABLUlaq/rrqFF4YeuZkkbHTFBMz288PUc3m3ZTcpN+E7+ZO
UBRZXKD20K07NugqCzUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEANWlOvyLEHdPV
8rMdfqLTZZyA79L1N3bP1FWS97fF36Y9EnTKChenwkBob1abY4jQ2/LICKND+ux8
xDlmMlYRH4aM5bXAjOcdpmq9R9SuzsK/2m79xONF//AX4zb0s5b+QEwdYkfJ5jiO
xMrnatwHQhFvQIQvuTo2o0WZEnkubNYDxVh7UOv9cOQjwm0+58CIEG5SHR9grG5u
TTswu7DswgpfSCKKPaFCF4pWxLfryYwadO0/4Ot/ZbElbAdJYC8CI1QC14knk2cD
0ZG9jaVPP9wCAt/ZIu8NbsZN7DNbISaXVfMju+xSdey8B3FLRkLq9TKmnLum5LR2
TyM6hDIh8A==
-----END CERTIFICATE-----
27 changes: 27 additions & 0 deletions boring/test/intermediate-ca.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEApyZi0joAIH8M7GaitH27lQs1XZaXwv5PI9bIeSkIX4BafIcU
I7hdPLreJoP6EsuoswXyhgZU8FQvNRjMAGPzvVviG+vY/l6jFI+JqW7Pphr35QJO
jqxwW/K/wYei0FS6C3SF+CJ2yIgG4YlJM9Hoq/EpfIxmyuZ2yHD/JiQ5kxNP7vKT
77f7k5zpCVG1kiQZKQT4iysQDz2e1ozi3W7NCDqnvM9+EX1DREiCqRUwuzIuTlkA
Z+8HpET5wS2Pm5uJQXDCid0slYMcuOL6JoHekbs69wkt4powcPPhXWoTCyUjpqsx
w0KPiBzViJUsd8JUq8ge+jVqP2pzvkQk4BWTMwIDAQABAoIBAFBiEHIjPH5kOzXQ
4fxE3xn9KuvYCSHYJP0KRJyn1AQBeQKb/15yQjx7bWw+WdwCHx4BBTHZB64P/ifd
xfWGG+h7sJBW6qLhpjG0GbLmvGuYWpDCfD72xI4jfn42mWDw7gumPOsov9EOQaji
2dZW4zsVHitsZd672HHqjXmtQBbvEcm/cuPoL2/s9crKwHbF90kb9BOYcz+/U138
zPfXFM5AbivpiQHA7CmMrQ833op42fQCfrxGs1XkZPO30EPpCtmHE6+Xhv+GGWp/
EF7D6pwkT4OElgzAP6cthPqZOtQLE2LCM/mTy/cFRtrBjKPlZ/UBrxjaLI1FHoAk
TYX81GECgYEA451EWFCrX5vWEMJE7zCALiQbxxOhQCIEufvkxUvDnsqjTPj/ylpZ
usu+YC5BcgwVxjso8dEL8pcd8pAFVLeX8wBDeGfTdhUmPPZmx8ViFbZTVq/Tz+Jw
tHo0foq8gfTLJrvdzuyFEHR6z5O16EtKOa+G1gIF/atV8hO/oRXLXvECgYEAu/7B
SpzbBJoxame27uaakYYVKuAD2wVAmfP9XuTV6IvE845sgmzTYURxSnO0RZCuNj5x
7u//HdGoFuA3o4Un4XLx1qot2op9ql1xuD/V3aqrvhpzvoCklks6t+PW3/Sef6TH
21TOCahpoQqD/UrSrHEJXC7lmkfcPCir3QflnGMCgYBV2AFnwXzwwShaB7rR7xvY
yxuC2H9vXaUks8DTPEDaCZjPNfXaznqa/a6ePbPHHJG1wqgtk2cLJj1QN0sbaWaw
akAIEDhrh4x1X4TiASp9/9askgGznLZfCtvzgcWYycc4o5ADM6b3zsZmtVHc+1BS
M0YKPpcd1dnDQ/l4+mxKMQKBgQCenCB+j/plVqaMjLaVty//yW2AgAIgvryzZ1yE
vHMRQSNJDgfUvnZVIUaoNxiIfLnPAD5mBkxq3yF/M2sd5lEwcCdEIs6PDLtbin1Q
o2MQI1fFC1JODwFN4GjJD0ySJTO4o9EO5uzyzwlXmqSjhoZagQARq2uCEFDq3LGr
yWba2wKBgDT+5qjFweI5RmE1pDvUH9gOPNflyOpyjnbueunmTn1rzcRhx9xgM3QB
ehWCRR1Y/vAnu5uupf0rG/Y/gtvIVyC3F+0csNox7T9e0t4sdgORYOVWbvsIF2t9
2HYjY782ws3EBF5yNKJDgV2sNjA0Wpb6lahkxRut314jnwGplR2w
-----END RSA PRIVATE KEY-----
21 changes: 21 additions & 0 deletions boring/test/intermediate-ca.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDdTCCAl2gAwIBAgIUE+pcEHU5e4wkMpp2qoyHy+wH8aMwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yNDAxMDMxMDM0MDdaFw0yNjA4
MTIxMDM0MDdaMFIxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMS4w
LAYDVQQKDCVJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQgSW50ZXJtZWRpYXRlMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApyZi0joAIH8M7GaitH27lQs1
XZaXwv5PI9bIeSkIX4BafIcUI7hdPLreJoP6EsuoswXyhgZU8FQvNRjMAGPzvVvi
G+vY/l6jFI+JqW7Pphr35QJOjqxwW/K/wYei0FS6C3SF+CJ2yIgG4YlJM9Hoq/Ep
fIxmyuZ2yHD/JiQ5kxNP7vKT77f7k5zpCVG1kiQZKQT4iysQDz2e1ozi3W7NCDqn
vM9+EX1DREiCqRUwuzIuTlkAZ+8HpET5wS2Pm5uJQXDCid0slYMcuOL6JoHekbs6
9wkt4powcPPhXWoTCyUjpqsxw0KPiBzViJUsd8JUq8ge+jVqP2pzvkQk4BWTMwID
AQABo1AwTjAdBgNVHQ4EFgQUZ3ELefSmoenETTa39CQwVzdoLZcwHwYDVR0jBBgw
FoAUbNOlA6sNXyzJjYqciKeId7g3/ZowDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B
AQsFAAOCAQEAHCXvCU1XQM5a7hhgrMcKQRto9GEVIljnPv5H7x+wPvCfR1By/kzI
fsl+hA1q02ymLtOW16aq4si4exsQl4SktC+5hyhu0yOCevRYXCcrh5NrNbwTFnK/
LIP4dRz4XBxC9pYg0rqvo+v64at6EBTXxYfBHo9Cj0QuZIJoYmGEOojdE0PudZdc
b1iuXk9FZlUueFq8uSkHD7EpxonPS9iWQA5dbw1Q+0hWqvA/npAvFXBHkF/Jyaht
fpqoUrr4LYUr/ShC1IVHG7TAEElnOGz0dY6uxkr1B6YxBvCJ6gesk2cJBC1i3g9I
9xvt4zxQNQynX0IHcar8xfgZqD4ZdWQY0w==
-----END CERTIFICATE-----
27 changes: 27 additions & 0 deletions boring/test/root-ca-2.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAwSgPW00nGOTje0FHm1HXT3ANHjW3HGPbxiMSRvSoBEdv8R9e
0PoKjse0xQsa5nKolbUhJBS6dkH+13VPOs6e+vZyXD6OYQfi2e42Mw0SPFl5g2qU
fy/17q3ipqPJnT6YHhGpx/P91F7yjDAF2MvNRGQ/6AYWD4MUr6+5vPHEYhQ/JlAK
cN/uWUM+bg2mwMNpmuGRV1tg0hKl9nT1fX1i6OSszPLIY1dC0eHv2gRh1unrXNoY
A76xohiwcJYAAPjrx167S8td8gmWnOwYnCnGIw2ceNpEQv4/bEvtKiLGOu4HUO/x
a7emy1QZgJth5TqQf0pwPEJC0mV5LFoXtlOpjwIDAQABAoIBAB3xBshhYlEikfy2
NtJl0ll3BiGLtBHLjPLe1uN242CebkTTVxBP4jkVzfjJaucUGPvz8uoz6F+ShV2C
ysBT7SL79uhDrjBuV4TuvyoUuaHvQL3VVKWOmrHf9IVeWE9ut4fZtxbOxKcZ/MEs
ZIuhs/UJETr3To4jBJ7jP4iBda66LXeGDwnhia04zpFWwRRyRFvdVwTvMm9TN2GY
21J6rnc44bGQ/l0qsxSrv/OuW3ZmFNz85mRbuLswgawJgjMSlt1orLz5mdofDxlz
898nSrpJq/mAj8kgV+sH2jGv5FVZrv30W/0GlXObiJLhJiywYkpXbSn/H//w9+ij
ItQXjDECgYEA9RNootH8F0vuWVezKrt9ApE+8AzwltDgMlFc/HEjINnKFg7SWsSN
oinPVcQ07PS+2E7Fgv/6IFv/RTATGIPYrNWGE17dR8xmwh+Xrexz45c49cHTwVCF
VM2J0PvlcEEAscMe1bd5HqIOJm+hvvqfwWdacUPZgtsaS9F/e33vj0cCgYEAycQx
c5EQ9T82z+qMhQ/mf63kYMYDsHbv6F92Pt38V24yh8NTW5lEcV+NonDFrPVH5Vd3
gU1lvXnG8e3Aj6EXOeEzfu9dpfdyqyZXIU2hbRPYuha+goBd03pM8+YEIgJX3ktu
1Q+G6uMrSLVbe+l06OEcYmvj8xGNWrk/3+ZiB3kCgYEA15+c92xjLSgcbDTyKU3O
Pj0Gr/Pilf7u0ratZlowew3DdMbToxK+PogkqKQ5oKXxZ6Vet9R6AJCQtxIGKxKN
x/sRvOdBL5OScYeUT2zzxbFeZzODGNm8hZFViS6nfq1ibARtk8Gaai5Q3tZm6/3c
IzDI7VCyBiS6LS0EyeVSqa8CgYBRmM6G9jvtcssv+qMpjOyi5iheGraTPwZ262Re
uFe85Av7a7riaHGNiB83enP3JpsU3PKvkCV9IyqZ3JTrgTJrbe/tfdBZtmDhZngG
N+b4vfYADAKvtEo9pFBKstMpDdmLROZltAnUJFr05KNC0X8+Twuzof5l5stLzW9P
lVQ/wQKBgQDT4ixRRx4DlMMzBXNRTkUuZloEhZtLC5xj71KhE7OeOdJ0e6DHJMg3
VDVQk+y3Qc+8Hh9yxMK/zrYLdHSVyvHTk+7AbppLGX7ZtyLm/gVq3l3VjWKmXKbm
ZT+3+2gqVyjr/p69T7/aLexvfzU5LdjwO7SQFNB4qZaG74WpGAlkMg==
-----END RSA PRIVATE KEY-----
20 changes: 20 additions & 0 deletions boring/test/root-ca-2.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDSzCCAjOgAwIBAgIUOQyKTQXHMKXZgwc5iktVZkL7hfwwDQYJKoZIhvcNAQEL
BQAwRzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxIzAhBgNVBAoM
GkludGVybmV0IFdpZGdpdHMgUHR5IEx0ZCAyMB4XDTIzMTIwNDEwMzA0N1oXDTIz
MTIxNDEwMzA0N1owRzELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
IzAhBgNVBAoMGkludGVybmV0IFdpZGdpdHMgUHR5IEx0ZCAyMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwSgPW00nGOTje0FHm1HXT3ANHjW3HGPbxiMS
RvSoBEdv8R9e0PoKjse0xQsa5nKolbUhJBS6dkH+13VPOs6e+vZyXD6OYQfi2e42
Mw0SPFl5g2qUfy/17q3ipqPJnT6YHhGpx/P91F7yjDAF2MvNRGQ/6AYWD4MUr6+5
vPHEYhQ/JlAKcN/uWUM+bg2mwMNpmuGRV1tg0hKl9nT1fX1i6OSszPLIY1dC0eHv
2gRh1unrXNoYA76xohiwcJYAAPjrx167S8td8gmWnOwYnCnGIw2ceNpEQv4/bEvt
KiLGOu4HUO/xa7emy1QZgJth5TqQf0pwPEJC0mV5LFoXtlOpjwIDAQABoy8wLTAd
BgNVHQ4EFgQU1rQttC2Y2T0HZAjzRkacyFLVBr8wDAYDVR0TBAUwAwEB/zANBgkq
hkiG9w0BAQsFAAOCAQEAsVucQLIzAKHwN/4ZuVOPpfy/B3+i/Stu2tvNhBxWpbh9
RQTa0ylpDfaAOLr+TfxCyT0/NmblK4QWxN6AJ5AZS9fVnstLhInafv7So0n3LCg5
eQkVcQtMdwHucfMw/iz7r229mOHBbK6cnZhu72rcnn7N/RlU+iEucfi6jO+r9iD1
y20glRta+wEqIBg7nGhulOwwdHVkX7ulpnXIqNCgNvU7/Mp7J+CxuWmeZKLvUQAh
D/gHs9kOPK4izN9QBrRwbiyTaD8G7kFlVWD1tPXrOhBdE1L4OJWvUDSfO0DKueIW
aQa2fFsR1iPuFX/jeTuPk5X2+u5eH4pXj13NEqKvOA==
-----END CERTIFICATE-----
Loading

0 comments on commit dfd49f4

Please sign in to comment.