1use std::{
24 cmp::Ordering,
25 convert::TryInto,
26 fmt::{self, Debug, Display, Formatter},
27 hash::Hash,
28 marker::PhantomData,
29 path::Path,
30 str,
31 time::{SystemTime, UNIX_EPOCH},
32};
33
34use casper_types::file_utils::{read_file, ReadFileError};
35use datasize::DataSize;
36use hex_fmt::HexFmt;
37use nid::Nid;
38use openssl::{
39 asn1::{Asn1Integer, Asn1IntegerRef, Asn1Time},
40 bn::{BigNum, BigNumContext},
41 ec::{self, EcKey},
42 error::ErrorStack,
43 hash::{DigestBytes, MessageDigest},
44 nid,
45 pkey::{PKey, PKeyRef, Private, Public},
46 sha,
47 ssl::{SslAcceptor, SslConnector, SslContextBuilder, SslMethod, SslVerifyMode, SslVersion},
48 x509::{X509Builder, X509Name, X509NameBuilder, X509NameRef, X509Ref, X509},
49};
50#[cfg(test)]
51use rand::{
52 distributions::{Distribution, Standard},
53 Rng,
54};
55use serde::{Deserialize, Serialize};
56use thiserror::Error;
57
58mod big_array {
61 use serde_big_array::big_array;
62
63 big_array! { BigArray; }
64}
65
66const SIGNATURE_ALGORITHM: Nid = Nid::ECDSA_WITH_SHA512;
68
69const SIGNATURE_CURVE: Nid = Nid::SECP521R1;
71
72const SIGNATURE_DIGEST: Nid = Nid::SHA512;
74
75type SslResult<T> = Result<T, ErrorStack>;
79
80#[derive(Copy, Clone, DataSize, Deserialize, Serialize)]
82pub struct Sha512(#[serde(with = "big_array::BigArray")] [u8; Sha512::SIZE]);
83
84impl Sha512 {
85 const SIZE: usize = 64;
87
88 const NID: Nid = Nid::SHA512;
90
91 pub fn new<B: AsRef<[u8]>>(data: B) -> Self {
93 let mut openssl_sha = sha::Sha512::new();
94 openssl_sha.update(data.as_ref());
95 Sha512(openssl_sha.finish())
96 }
97
98 fn bytes(&self) -> &[u8] {
100 let bs = &self.0[..];
101
102 debug_assert_eq!(bs.len(), Self::SIZE);
103 bs
104 }
105
106 fn from_openssl_digest(digest: &DigestBytes) -> Self {
108 let digest_bytes = digest.as_ref();
109
110 debug_assert_eq!(
111 digest_bytes.len(),
112 Self::SIZE,
113 "digest is not the right size - check constants in `tls.rs`"
114 );
115
116 let mut buf = [0; Self::SIZE];
117 buf.copy_from_slice(&digest_bytes[0..Self::SIZE]);
118
119 Sha512(buf)
120 }
121
122 fn create_message_digest() -> MessageDigest {
124 MessageDigest::from_nid(Self::NID).expect("Sha512::NID is invalid")
127 }
128}
129
130#[derive(Copy, Clone, DataSize, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
132pub(crate) struct CertFingerprint(Sha512);
133
134impl Debug for CertFingerprint {
135 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
136 write!(f, "CertFingerprint({:10})", HexFmt(self.0.bytes()))
137 }
138}
139
140#[derive(Copy, Clone, DataSize, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
142pub struct KeyFingerprint(Sha512);
143
144impl KeyFingerprint {
145 pub const LENGTH: usize = Sha512::SIZE;
147}
148
149impl AsRef<[u8]> for KeyFingerprint {
150 fn as_ref(&self) -> &[u8] {
151 self.0.bytes()
152 }
153}
154
155impl Debug for KeyFingerprint {
156 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
157 write!(f, "KeyFingerprint({:10})", HexFmt(self.0.bytes()))
158 }
159}
160
161impl From<[u8; KeyFingerprint::LENGTH]> for KeyFingerprint {
162 fn from(raw_bytes: [u8; KeyFingerprint::LENGTH]) -> Self {
163 KeyFingerprint(Sha512(raw_bytes))
164 }
165}
166
167impl From<Sha512> for KeyFingerprint {
168 fn from(hash: Sha512) -> Self {
169 Self(hash)
170 }
171}
172
173#[cfg(test)]
174impl Distribution<KeyFingerprint> for Standard {
175 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> KeyFingerprint {
176 let mut bytes = [0u8; Sha512::SIZE];
177 rng.fill(&mut bytes[..]);
178 bytes.into()
179 }
180}
181
182#[derive(Clone, Deserialize, Eq, Hash, PartialEq, Serialize)]
184struct Signature(Vec<u8>);
185
186impl Debug for Signature {
187 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
188 write!(f, "Signature({:10})", HexFmt(&self.0))
189 }
190}
191
192#[derive(Clone, DataSize)]
196pub struct TlsCert {
197 #[data_size(skip)] x509: X509,
200
201 cert_fingerprint: CertFingerprint,
203
204 key_fingerprint: KeyFingerprint,
206}
207
208impl TlsCert {
209 pub(crate) fn fingerprint(&self) -> CertFingerprint {
214 self.cert_fingerprint
215 }
216
217 pub(crate) fn public_key_fingerprint(&self) -> KeyFingerprint {
219 self.key_fingerprint
220 }
221
222 pub(crate) fn as_x509(&self) -> &X509 {
224 &self.x509
225 }
226}
227
228impl Debug for TlsCert {
229 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
230 write!(f, "TlsCert({:?})", self.fingerprint())
231 }
232}
233
234impl Hash for TlsCert {
235 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
236 self.fingerprint().hash(state);
237 }
238}
239
240impl PartialEq for TlsCert {
241 fn eq(&self, other: &Self) -> bool {
242 self.fingerprint() == other.fingerprint()
243 }
244}
245
246impl Eq for TlsCert {}
247
248#[derive(Debug, Error, Serialize)]
250pub enum LoadCertError {
251 #[error("could not load certificate file: {0}")]
252 ReadFile(
253 #[serde(skip_serializing)]
254 #[source]
255 ReadFileError,
256 ),
257 #[error("unable to load x509 certificate {0:?}")]
258 X509CertFromPem(
259 #[serde(skip_serializing)]
260 #[source]
261 ErrorStack,
262 ),
263}
264
265pub(crate) fn load_cert<P: AsRef<Path>>(src: P) -> Result<X509, LoadCertError> {
267 let pem = read_file(src.as_ref()).map_err(LoadCertError::ReadFile)?;
268 X509::from_pem(&pem).map_err(LoadCertError::X509CertFromPem)
269}
270
271#[derive(Debug, Error, Serialize)]
273pub(crate) enum LoadSecretKeyError {
274 #[error("could not load secret key file: {0}")]
275 ReadFile(
276 #[serde(skip_serializing)]
277 #[source]
278 ReadFileError,
279 ),
280 #[error("unable to load private key from pem {0:?}")]
281 PrivateKeyFromPem(
282 #[serde(skip_serializing)]
283 #[source]
284 ErrorStack,
285 ),
286}
287
288pub(crate) fn load_secret_key<P: AsRef<Path>>(src: P) -> Result<PKey<Private>, LoadSecretKeyError> {
289 let pem = read_file(src.as_ref()).map_err(LoadSecretKeyError::ReadFile)?;
290 PKey::private_key_from_pem(&pem).map_err(LoadSecretKeyError::PrivateKeyFromPem)
291}
292
293#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
298pub struct Signed<V> {
299 data: Vec<u8>,
300 signature: Signature,
301 _phantom: PhantomData<V>,
302}
303
304pub fn generate_node_cert() -> SslResult<(X509, PKey<Private>)> {
308 let private_key = generate_private_key()?;
309 let cert = generate_cert(&private_key, "casper-node")?;
310
311 Ok((cert, private_key))
312}
313
314pub(crate) fn create_tls_acceptor(
321 cert: &X509Ref,
322 private_key: &PKeyRef<Private>,
323) -> SslResult<SslAcceptor> {
324 let mut builder = SslAcceptor::mozilla_modern_v5(SslMethod::tls_server())?;
325 set_context_options(&mut builder, cert, private_key)?;
326
327 Ok(builder.build())
328}
329
330pub(crate) fn create_tls_connector(
335 cert: &X509Ref,
336 private_key: &PKeyRef<Private>,
337) -> SslResult<SslConnector> {
338 let mut builder = SslConnector::builder(SslMethod::tls_client())?;
339 set_context_options(&mut builder, cert, private_key)?;
340
341 Ok(builder.build())
342}
343
344fn set_context_options(
348 ctx: &mut SslContextBuilder,
349 cert: &X509Ref,
350 private_key: &PKeyRef<Private>,
351) -> SslResult<()> {
352 ctx.set_min_proto_version(Some(SslVersion::TLS1_3))?;
353
354 ctx.set_certificate(cert)?;
355 ctx.set_private_key(private_key)?;
356 ctx.check_private_key()?;
357
358 ctx.set_verify_callback(SslVerifyMode::PEER, |_, _| true);
363
364 Ok(())
365}
366
367#[derive(Debug, Error, Serialize)]
369pub enum ValidationError {
370 #[error("error reading public key from certificate: {0:?}")]
372 CannotReadPublicKey(
373 #[serde(skip_serializing)]
374 #[source]
375 ErrorStack,
376 ),
377 #[error("error reading subject or issuer name: {0:?}")]
379 CorruptSubjectOrIssuer(
380 #[serde(skip_serializing)]
381 #[source]
382 ErrorStack,
383 ),
384 #[error("wrong signature scheme")]
386 WrongSignatureAlgorithm,
387 #[error("there was an issue reading or converting times: {0:?}")]
389 TimeIssue(
390 #[serde(skip_serializing)]
391 #[source]
392 ErrorStack,
393 ),
394 #[error("the certificate is not yet valid")]
396 NotYetValid,
397 #[error("the certificate expired")]
399 Expired,
400 #[error("the serial number could not be compared to the reference: {0:?}")]
402 InvalidSerialNumber(
403 #[serde(skip_serializing)]
404 #[source]
405 ErrorStack,
406 ),
407 #[error("wrong serial number")]
409 WrongSerialNumber,
410 #[error("no valid elliptic curve key could be extracted from certificate: {0:?}")]
412 CouldNotExtractEcKey(
413 #[serde(skip_serializing)]
414 #[source]
415 ErrorStack,
416 ),
417 #[error("the given public key fails basic sanity checks: {0:?}")]
419 KeyFailsCheck(
420 #[serde(skip_serializing)]
421 #[source]
422 ErrorStack,
423 ),
424 #[error("underlying elliptic curve is wrong")]
426 WrongCurve,
427 #[error("certificate is not self-signed")]
429 NotSelfSigned,
430 #[error("the signature could not be validated")]
432 FailedToValidateSignature(
433 #[serde(skip_serializing)]
434 #[source]
435 ErrorStack,
436 ),
437 #[error("the signature is invalid")]
439 InvalidSignature,
440 #[error("failed to read fingerprint")]
442 InvalidFingerprint(
443 #[serde(skip_serializing)]
444 #[source]
445 ErrorStack,
446 ),
447 #[error("could not create a big num context")]
449 BigNumContextNotAvailable(
450 #[serde(skip_serializing)]
451 #[source]
452 ErrorStack,
453 ),
454 #[error("could not encode public key as bytes")]
456 PublicKeyEncodingFailed(
457 #[serde(skip_serializing)]
458 #[source]
459 ErrorStack,
460 ),
461 #[error("the certificate is not signed by provided certificate authority")]
463 WrongCertificateAuthority,
464 #[error("error reading public key from ca certificate: {0:?}")]
466 CannotReadCAPublicKey(
467 #[serde(skip_serializing)]
468 #[source]
469 ErrorStack,
470 ),
471}
472
473pub(crate) fn validate_cert_with_authority(
476 cert: X509,
477 ca: &X509,
478) -> Result<TlsCert, ValidationError> {
479 let authority_key = ca
480 .public_key()
481 .map_err(ValidationError::CannotReadCAPublicKey)?;
482
483 validate_cert_expiration_date(&cert)?;
484
485 if !cert
486 .verify(authority_key.as_ref())
487 .map_err(ValidationError::FailedToValidateSignature)?
488 {
489 return Err(ValidationError::WrongCertificateAuthority);
490 }
491
492 tls_cert_from_x509(cert)
494}
495
496pub(crate) fn validate_self_signed_cert(cert: X509) -> Result<TlsCert, ValidationError> {
501 if cert.signature_algorithm().object().nid() != SIGNATURE_ALGORITHM {
502 return Err(ValidationError::WrongSignatureAlgorithm);
505 }
506 let subject =
511 name_to_string(cert.subject_name()).map_err(ValidationError::CorruptSubjectOrIssuer)?;
512 let issuer =
513 name_to_string(cert.issuer_name()).map_err(ValidationError::CorruptSubjectOrIssuer)?;
514 if subject != issuer {
515 return Err(ValidationError::NotSelfSigned);
517 }
518
519 if !num_eq(cert.serial_number(), 1).map_err(ValidationError::InvalidSerialNumber)? {
521 return Err(ValidationError::WrongSerialNumber);
522 }
523
524 validate_cert_expiration_date(&cert)?;
526
527 let (public_key, ec_key) = validate_cert_ec_key(&cert)?;
529 if ec_key.group().curve_name() != Some(SIGNATURE_CURVE) {
530 return Err(ValidationError::WrongCurve);
532 }
533
534 if !cert
536 .verify(&public_key)
537 .map_err(ValidationError::FailedToValidateSignature)?
538 {
539 return Err(ValidationError::InvalidSignature);
540 }
541
542 tls_cert_from_x509_and_key(cert, ec_key)
543}
544
545pub(crate) fn tls_cert_from_x509(cert: X509) -> Result<TlsCert, ValidationError> {
550 let (_public_key, ec_key) = validate_cert_ec_key(&cert)?;
551 tls_cert_from_x509_and_key(cert, ec_key)
552}
553
554fn tls_cert_from_x509_and_key(
555 cert: X509,
556 ec_key: EcKey<Public>,
557) -> Result<TlsCert, ValidationError> {
558 let cert_fingerprint = cert_fingerprint(&cert)?;
559 let key_fingerprint = key_fingerprint(&ec_key)?;
560 Ok(TlsCert {
561 x509: cert,
562 cert_fingerprint,
563 key_fingerprint,
564 })
565}
566
567pub(crate) fn cert_fingerprint(cert: &X509) -> Result<CertFingerprint, ValidationError> {
569 assert_eq!(Sha512::NID, SIGNATURE_DIGEST);
570 let digest = &cert
571 .digest(Sha512::create_message_digest())
572 .map_err(ValidationError::InvalidFingerprint)?;
573 let cert_fingerprint = CertFingerprint(Sha512::from_openssl_digest(digest));
574 Ok(cert_fingerprint)
575}
576
577pub(crate) fn key_fingerprint(ec_key: &EcKey<Public>) -> Result<KeyFingerprint, ValidationError> {
579 let mut big_num_context =
580 BigNumContext::new().map_err(ValidationError::BigNumContextNotAvailable)?;
581 let buf = ec_key
582 .public_key()
583 .to_bytes(
584 ec::EcGroup::from_curve_name(SIGNATURE_CURVE)
585 .expect("broken constant SIGNATURE_CURVE")
586 .as_ref(),
587 ec::PointConversionForm::COMPRESSED,
588 &mut big_num_context,
589 )
590 .map_err(ValidationError::PublicKeyEncodingFailed)?;
591 let key_fingerprint = KeyFingerprint(Sha512::new(buf));
592 Ok(key_fingerprint)
593}
594
595fn validate_cert_ec_key(cert: &X509) -> Result<(PKey<Public>, EcKey<Public>), ValidationError> {
597 let public_key = cert
598 .public_key()
599 .map_err(ValidationError::CannotReadPublicKey)?;
600 let ec_key = public_key
601 .ec_key()
602 .map_err(ValidationError::CouldNotExtractEcKey)?;
603 ec_key.check_key().map_err(ValidationError::KeyFailsCheck)?;
604 Ok((public_key, ec_key))
605}
606
607fn validate_cert_expiration_date(cert: &X509) -> Result<(), ValidationError> {
609 let asn1_now = Asn1Time::from_unix(now()).map_err(ValidationError::TimeIssue)?;
610 if asn1_now
611 .compare(cert.not_before())
612 .map_err(ValidationError::TimeIssue)?
613 != Ordering::Greater
614 {
615 return Err(ValidationError::NotYetValid);
616 }
617
618 if asn1_now
619 .compare(cert.not_after())
620 .map_err(ValidationError::TimeIssue)?
621 != Ordering::Less
622 {
623 return Err(ValidationError::Expired);
624 }
625
626 Ok(())
627}
628
629fn now() -> i64 {
631 let now = SystemTime::now();
634 let ts: i64 = now
635 .duration_since(UNIX_EPOCH)
636 .expect("Great Scott! Your clock is horribly broken, Marty.")
638 .as_secs()
639 .try_into()
642 .expect("32-bit systems and far future are not supported");
643
644 ts
645}
646
647fn mknum(n: u32) -> Result<Asn1Integer, ErrorStack> {
649 let bn = BigNum::from_u32(n)?;
650
651 bn.to_asn1_integer()
652}
653
654fn mkname(c: &str, o: &str, cn: &str) -> Result<X509Name, ErrorStack> {
658 let mut builder = X509NameBuilder::new()?;
659
660 if !c.is_empty() {
661 builder.append_entry_by_text("C", c)?;
662 }
663
664 if !o.is_empty() {
665 builder.append_entry_by_text("O", o)?;
666 }
667
668 builder.append_entry_by_text("CN", cn)?;
669 Ok(builder.build())
670}
671
672fn name_to_string(name: &X509NameRef) -> SslResult<String> {
674 let mut output = String::new();
675
676 for entry in name.entries() {
677 output.push_str(entry.object().nid().long_name()?);
678 output.push('=');
679 output.push_str(entry.data().as_utf8()?.as_ref());
680 output.push(' ');
681 }
682
683 Ok(output)
684}
685
686fn num_eq(num: &Asn1IntegerRef, other: u32) -> SslResult<bool> {
688 let l = num.to_bn()?;
689 let r = BigNum::from_u32(other)?;
690
691 Ok(l.is_negative() == r.is_negative() && l.ucmp(r.as_ref()) == Ordering::Equal)
693}
694
695fn generate_private_key() -> SslResult<PKey<Private>> {
697 let ec_group = ec::EcGroup::from_curve_name(SIGNATURE_CURVE)?;
713 let ec_key = EcKey::generate(ec_group.as_ref())?;
714
715 PKey::from_ec_key(ec_key)
716}
717
718fn generate_cert(private_key: &PKey<Private>, cn: &str) -> SslResult<X509> {
720 let mut builder = X509Builder::new()?;
721
722 builder.set_version(2)?;
724
725 builder.set_serial_number(mknum(1)?.as_ref())?;
727
728 let issuer = mkname("US", "Casper Blockchain", cn)?;
729
730 builder.set_issuer_name(issuer.as_ref())?;
732 builder.set_subject_name(issuer.as_ref())?;
733
734 let ts = now();
735 builder.set_not_before(Asn1Time::from_unix(ts - 60)?.as_ref())?;
737
738 builder.set_not_after(Asn1Time::from_unix(ts + 10 * 365 * 24 * 60 * 60)?.as_ref())?;
740
741 builder.set_pubkey(private_key.as_ref())?;
743 assert_eq!(Sha512::NID, SIGNATURE_DIGEST);
744 builder.sign(private_key.as_ref(), Sha512::create_message_digest())?;
745
746 let cert = builder.build();
747
748 assert!(
750 validate_self_signed_cert(cert.clone()).is_ok(),
751 "newly generated cert does not pass our own validity check"
752 );
753
754 Ok(cert)
755}
756
757impl PartialEq for Sha512 {
760 #[inline]
761 fn eq(&self, other: &Self) -> bool {
762 self.bytes() == other.bytes()
763 }
764}
765
766impl Eq for Sha512 {}
767
768impl Ord for Sha512 {
769 #[inline]
770 fn cmp(&self, other: &Self) -> Ordering {
771 Ord::cmp(self.bytes(), other.bytes())
772 }
773}
774
775impl PartialOrd for Sha512 {
776 #[inline]
777 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
778 Some(Ord::cmp(self, other))
779 }
780}
781
782impl Debug for Sha512 {
783 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
784 write!(f, "{}", base16::encode_lower(&self.0[..]))
785 }
786}
787
788impl Display for Sha512 {
789 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
790 write!(f, "{:10}", HexFmt(&self.0[..]))
791 }
792}
793
794impl Display for CertFingerprint {
795 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
796 Display::fmt(&self.0, f)
797 }
798}
799
800impl Display for KeyFingerprint {
801 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
802 write!(f, "{:10}", HexFmt(self.0.bytes()))
803 }
804}
805
806impl Display for Signature {
807 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
808 write!(f, "{:10}", HexFmt(&self.0[..]))
809 }
810}
811
812impl<T> Display for Signed<T>
813where
814 T: Display + for<'de> Deserialize<'de>,
815{
816 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
817 match bincode::deserialize::<T>(self.data.as_slice()) {
819 Ok(item) => write!(f, "signed[{}]<{} bytes>", self.signature, item),
820 Err(_err) => write!(f, "signed[{}]<CORRUPT>", self.signature),
821 }
822 }
823}
824
825impl Hash for Sha512 {
831 #[inline]
832 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
833 let mut chunk = [0u8; 8];
835
836 chunk.copy_from_slice(&self.bytes()[0..8]);
838
839 state.write_u64(u64::from_le_bytes(chunk));
840 }
841}
842
843#[cfg(test)]
844mod tests {
845 use super::*;
846
847 #[test]
848 fn simple_name_to_string() {
849 let name = mkname("sc", "some_org", "some_cn").expect("could not create name");
850
851 assert_eq!(
852 name_to_string(name.as_ref()).expect("name to string failed"),
853 "countryName=sc organizationName=some_org commonName=some_cn "
854 );
855 }
856
857 #[test]
858 fn test_validate_self_signed_cert() {
859 let (cert, private_key) = generate_node_cert().expect("failed to generate key, cert pair");
860
861 let _tls_cert =
863 validate_self_signed_cert(cert).expect("generated self signed cert is not valid");
864
865 let ca_private_key = generate_private_key().expect("failed to generate private key");
867 let ca_signed_cert = make_ca_signed_cert(private_key, ca_private_key);
868
869 let error = validate_self_signed_cert(ca_signed_cert)
870 .expect_err("should not validate ca signed cert as self signed");
871 assert!(
872 matches!(error, ValidationError::InvalidSignature),
873 "{:?}",
874 error
875 );
876 }
877
878 #[test]
879 fn test_validate_cert_with_authority() {
880 let (ca_cert, ca_private_key) =
881 generate_node_cert().expect("failed to generate key, cert pair");
882
883 let (different_ca_cert, _ca_private_key) =
884 generate_node_cert().expect("failed to generate key, cert pair");
885
886 let node_private_key = generate_private_key().expect("failed to generate private key");
887
888 let node_cert = make_ca_signed_cert(node_private_key, ca_private_key);
889
890 validate_self_signed_cert(node_cert.clone())
891 .expect_err("should not validate CA signed cert as self signed");
892
893 let _node_tls_cert = validate_cert_with_authority(node_cert.clone(), &ca_cert)
894 .expect("should validate with ca cert");
895
896 let validation_error = validate_cert_with_authority(node_cert, &different_ca_cert)
897 .expect_err("should not validate cert against different CA");
898
899 assert!(
900 matches!(validation_error, ValidationError::WrongCertificateAuthority),
901 "{:?}",
902 validation_error
903 );
904 }
905
906 fn make_ca_signed_cert(private_key: PKey<Private>, ca_private_key: PKey<Private>) -> X509 {
907 let mut builder = X509Builder::new().unwrap();
908 builder.set_version(2).unwrap();
909 builder
910 .set_serial_number(mknum(1).unwrap().as_ref())
911 .unwrap();
912 let issuer = mkname("US", "Casper Blockchain", "Casper Network").unwrap();
913 builder.set_issuer_name(issuer.as_ref()).unwrap();
914 builder.set_subject_name(issuer.as_ref()).unwrap();
915 let ts = now();
916 builder
917 .set_not_before(Asn1Time::from_unix(ts - 60).unwrap().as_ref())
918 .unwrap();
919 builder
920 .set_not_after(
921 Asn1Time::from_unix(ts + 10 * 365 * 24 * 60 * 60)
922 .unwrap()
923 .as_ref(),
924 )
925 .unwrap();
926 builder.set_pubkey(private_key.as_ref()).unwrap();
927 assert_eq!(Sha512::NID, SIGNATURE_DIGEST);
928 builder
929 .sign(ca_private_key.as_ref(), Sha512::create_message_digest())
930 .unwrap();
931 builder.build()
932 }
933}