def Start(self): """Sign the CSR from the client.""" with aff4.FACTORY.Create(self.client_id, aff4_grr.VFSGRRClient, mode="rw", token=self.token) as client: if self.args.csr.type != rdf_crypto.Certificate.Type.CSR: raise IOError("Must be called with CSR") csr = rdf_crypto.CertificateSigningRequest(self.args.csr.pem) # Verify the CSR. This is not strictly necessary but doesn't harm either. try: csr.Verify(csr.GetPublicKey()) except rdf_crypto.VerificationError: raise flow.FlowError("CSR for client %s did not verify: %s" % (self.client_id, csr.AsPEM())) # Verify that the CN is of the correct form. The common name should refer # to a client URN. self.cn = rdf_client.ClientURN.FromPublicKey(csr.GetPublicKey()) if self.cn != csr.GetCN(): raise IOError("CSR CN %s does not match public key %s." % (csr.GetCN(), self.cn)) logging.info("Will sign CSR for: %s", self.cn) cert = rdf_crypto.RDFX509Cert.ClientCertFromCSR(csr) # This check is important to ensure that the client id reported in the # source of the enrollment request is the same as the one in the # certificate. We use the ClientURN to ensure this is also of the correct # form for a client name. if self.cn != self.client_id: raise flow.FlowError( "Certificate name %s mismatch for client %s", self.cn, self.client_id) # Set and write the certificate to the client record. now = rdfvalue.RDFDatetime.Now() client.Set(client.Schema.CERT, cert) client.Set(client.Schema.FIRST_SEEN, now) if data_store.RelationalDBEnabled(): data_store.REL_DB.WriteClientMetadata( self.client_id.Basename(), certificate=cert, first_seen=now, fleetspeak_enabled=False) index = client_index.CreateClientIndex(token=self.token) index.AddClient(client) if data_store.RelationalDBEnabled: index = client_index.ClientIndex() index.AddClient(self.client_id.Basename(), data_migration.ConvertVFSGRRClient(client)) # Publish the client enrollment message. self.Publish("ClientEnrollment", self.client_id) self.Log("Enrolled %s successfully", self.client_id)
def Start(self): """Sign the CSR from the client.""" client = aff4.FACTORY.Create(self.client_id, aff4_grr.VFSGRRClient, mode="rw", token=self.token) if self.args.csr.type != rdf_crypto.Certificate.Type.CSR: raise IOError("Must be called with CSR") csr = rdf_crypto.CertificateSigningRequest(self.args.csr.pem) # Verify the CSR. This is not strictly necessary but doesn't harm either. try: csr.Verify(csr.GetPublicKey()) except rdf_crypto.VerificationError: raise flow.FlowError("CSR for client %s did not verify: %s" % (self.client_id, csr.AsPEM())) # Verify that the CN is of the correct form. The common name should refer # to a client URN. self.cn = rdf_client.ClientURN.FromPublicKey(csr.GetPublicKey()) if self.cn != csr.GetCN(): raise IOError("CSR CN %s does not match public key %s." % (csr.GetCN(), self.cn)) logging.info("Will sign CSR for: %s", self.cn) cert = rdf_crypto.RDFX509Cert.ClientCertFromCSR(csr) # This check is important to ensure that the client id reported in the # source of the enrollment request is the same as the one in the # certificate. We use the ClientURN to ensure this is also of the correct # form for a client name. if self.cn != self.client_id: raise flow.FlowError("Certificate name %s mismatch for client %s", self.cn, self.client_id) # Set and write the certificate to the client record. client.Set(client.Schema.CERT, cert) client.Set(client.Schema.FIRST_SEEN, rdfvalue.RDFDatetime.Now()) index = aff4.FACTORY.Create(client_index.MAIN_INDEX, aff4_type=client_index.ClientIndex, object_exists=True, mode="rw", token=self.token) index.AddClient(client) client.Close(sync=True) # Publish the client enrollment message. self.Publish("ClientEnrollment", self.client_id) self.Log("Enrolled %s successfully", self.client_id)
def testCertificateValidation(self): private_key = rdf_crypto.RSAPrivateKey.GenerateKey() csr = rdf_crypto.CertificateSigningRequest( common_name="C.0000000000000001", private_key=private_key) client_cert = rdf_crypto.RDFX509Cert.ClientCertFromCSR(csr) now = rdfvalue.RDFDatetime.Now() now_plus_year_and_a_bit = now + rdfvalue.Duration("55w") now_minus_a_bit = now - rdfvalue.Duration("1h") with test_lib.FakeTime(now_plus_year_and_a_bit): with self.assertRaises(rdf_crypto.VerificationError): client_cert.Verify(private_key.GetPublicKey()) with test_lib.FakeTime(now_minus_a_bit): with self.assertRaises(rdf_crypto.VerificationError): client_cert.Verify(private_key.GetPublicKey())
def testCertificateVerification(self): private_key = rdf_crypto.RSAPrivateKey.GenerateKey() csr = rdf_crypto.CertificateSigningRequest( common_name="C.0000000000000001", private_key=private_key) client_cert = rdf_crypto.RDFX509Cert.ClientCertFromCSR(csr) ca_signing_key = config_lib.CONFIG["PrivateKeys.ca_key"] csr.Verify(private_key.GetPublicKey()) client_cert.Verify(ca_signing_key.GetPublicKey()) wrong_key = rdf_crypto.RSAPrivateKey.GenerateKey() with self.assertRaises(rdf_crypto.VerificationError): csr.Verify(wrong_key.GetPublicKey()) with self.assertRaises(rdf_crypto.VerificationError): client_cert.Verify(wrong_key.GetPublicKey())