def _create_cert(self, fcn, subject_key, issuer_key, not_before, not_after): """ :param callable fcn The function from the certs package to call to generate the cert. :param Key issuer_key If it is None, then self signed. """ subject_id = subject_key.AS.isd_as_str() not_before, not_after = validity(Validity(not_before, not_after), subject_key, issuer_key) kwargs = {} if issuer_key is not None: kwargs = { 'issuer_key': keys.decode_key(issuer_key.key), 'issuer_id': issuer_key.AS.isd_as_str() } cert = fcn(subject_id=subject_id, subject_key=keys.decode_key(subject_key.key), not_before=not_before, not_after=not_after, **kwargs) version = Certificate.next_version(subject_key.AS, subject_key.usage) cert = super().create( key=subject_key, version=version, not_before=not_before, not_after=not_after, certificate=certs.encode_certificate(cert), # PEM encoded ) cert.ca_cert = issuer_key.certificates.latest( issuer_key.usage) if issuer_key else cert cert.save() return cert
def _sign_payload(self, temp_dir: str, cert: str, key: str) -> bytes: """ signs the payload with one signer """ sb = pkcs7.PKCS7SignatureBuilder(Path(temp_dir, self.PAYLOAD_FILENAME).read_bytes())\ .add_signer(certs.decode_certificate(cert), keys.decode_key(key), hashes.SHA512()) return sb.sign(serialization.Encoding.DER, [ pkcs7.PKCS7Options.NoCerts, pkcs7.PKCS7Options.NoCapabilities, pkcs7.PKCS7Options.Binary ])
def regenerate_ases(): # get the CA key with open('ca-ff00_0_110.key', 'r') as f: ca_key = decode_key(f.read()) issuer = (ca_key, _create_name('1-ff00:0:110', '1-ff00:0:110 Secure CA Certificate')) # and generate for asid in ['1-ff00:0:110', '1-ff00:0:111', '1-ff00:0:112']: key = generate_key() cert = _build_certificate(subject=(key, _create_name(asid, f'Regular AS {asid}')), issuer=issuer, not_before=datetime.utcnow(), not_after=datetime.utcnow() + timedelta(days=1), extensions=_build_extensions_as(key, issuer[0])) fasid = asid.replace(':', '_') with open(f'as{fasid}.key', 'w') as f: f.write(encode_key(key)) with open(f'as{fasid}.crt', 'w') as f: f.write(encode_certificate(cert))
def test_sign_other_certificate(self): # list of (cert, key) signers = _get_signers( ['voting-sensitive-ff00_0_110', 'voting-regular-ff00_0_110']) # replace the first certificate with a new, valid, one, generated from the key key = signers[0][1] # key at index 1, cert at index 0 orig_cert = certs.decode_certificate(signers[0][0]) cert = certs.generate_voting_sensitive_certificate( '1-ff00:0:110', keys.decode_key(key), not_before=orig_cert.not_valid_before, not_after=orig_cert.not_valid_after) # sanity check for the new certificate: self.assertEqual(cert.subject, orig_cert.subject) self.assertEqual(cert.issuer, orig_cert.issuer) self.assertEqual(cert.not_valid_before, orig_cert.not_valid_before) self.assertEqual(cert.not_valid_after, orig_cert.not_valid_after) self.assertNotEqual(cert.serial_number, orig_cert.serial_number) self.assertNotEqual(cert.signature, orig_cert.signature) # actually replace the certificate in the signers list, keep the key signers[0] = (certs.encode_certificate(cert), signers[0][1]) # and go on as usual conf = TRCConf(**_transform_toml_conf_to_trcconf_args( toml.loads( Path(_TESTDATA_DIR, 'payload-1-config.toml').read_text()))) signed_payloads = [] with TemporaryDirectory() as temp_dir: conf._dump_certificates_to_files(temp_dir) conf._gen_payload(temp_dir) for (cert, key) in signers: signed_payloads.append(conf._sign_payload(temp_dir, cert, key)) trc = conf._combine(temp_dir, *signed_payloads) # verify the trc with a call to scion-pki (would raise if error) with self.assertRaises(ScionPkiError): verify_trcs(trc, trc)