def CreateTimelineFixture(self): """Creates a new timeline fixture we can play with.""" # Create a client for testing client_id = rdf_client.ClientURN("C.0000000000000001") token = access_control.ACLToken(username="******", reason="fixture") fd = aff4.FACTORY.Create(client_id, "VFSGRRClient", token=token) cert = self.ClientCertFromPrivateKey( config_lib.CONFIG["Client.private_key"]) client_cert = rdf_crypto.RDFX509Cert(cert.as_pem()) fd.Set(fd.Schema.CERT(client_cert)) fd.Close() with test_lib.VFSOverrider( rdf_paths.PathSpec.PathType.OS, test_lib.ClientVFSHandlerFixture): client_mock = action_mocks.ActionMock("ListDirectory") output_path = "analysis/Timeline/MAC" for _ in test_lib.TestFlowHelper( "RecursiveListDirectory", client_mock, client_id=client_id, pathspec=rdf_paths.PathSpec( path="/", pathtype=rdf_paths.PathSpec.PathType.OS), token=token): pass # Now make a timeline for _ in test_lib.TestFlowHelper( "MACTimes", client_mock, client_id=client_id, token=token, path="/", output=output_path): pass
def MakeCASignedCert(common_name, private_key, ca_cert, ca_private_key, serial_number=2): """Make a cert and sign it with the CA's private key.""" public_key = private_key.GetPublicKey() builder = x509.CertificateBuilder() builder = builder.issuer_name(ca_cert.GetIssuer()) subject = x509.Name( [x509.NameAttribute(oid.NameOID.COMMON_NAME, common_name)]) builder = builder.subject_name(subject) valid_from = rdfvalue.RDFDatetime.Now() - rdfvalue.Duration("1d") valid_until = rdfvalue.RDFDatetime.Now() + rdfvalue.Duration("3650d") builder = builder.not_valid_before(valid_from.AsDatetime()) builder = builder.not_valid_after(valid_until.AsDatetime()) builder = builder.serial_number(serial_number) builder = builder.public_key(public_key.GetRawPublicKey()) builder = builder.add_extension( x509.BasicConstraints(ca=False, path_length=None), critical=True) certificate = builder.sign( private_key=ca_private_key.GetRawPrivateKey(), algorithm=hashes.SHA256(), backend=openssl.backend) return rdf_crypto.RDFX509Cert(certificate)
def Run(self, args): file_fd = vfs.VFSOpen(args.pathspec, progress_callback=self.Progress) # Gzip the original file. gzip_fd = uploads.GzipWrapper(file_fd) # And then encrypt it. server_certificate = rdf_crypto.RDFX509Cert( self.grr_worker.client.server_certificate) fd = uploads.EncryptStream(server_certificate.GetPublicKey(), config_lib.CONFIG["Client.private_key"], gzip_fd) response = self.grr_worker.http_manager.OpenServerEndpoint( u"/upload/", data=self.FileGenerator(fd), headers={ "x-grr-hmac": base64.b64encode(args.hmac), "x-grr-policy": base64.b64encode(args.policy), }, method="POST") if response.code != 200: raise IOError("Unable to upload %s" % args.pathspec.CollapsePath()) logging.debug("Uploaded %s (%s bytes)", args.pathspec, self.sent_data) stat_entry = file_fd.Stat() # Sometimes the file we upload does not report its correct size in the # st_size attribute (e.g. /proc files). We modify the st_size to force it to # report the actual amount of data uploaded. stat_entry.st_size = self.sent_data self.SendReply(stat_entry)
def Run(self, args): file_fd = vfs.VFSOpen(args.pathspec, progress_callback=self.Progress) # Gzip the original file. gzip_fd = uploads.GzipWrapper(file_fd) # And then encrypt it. server_certificate = rdf_crypto.RDFX509Cert( self.grr_worker.client.server_certificate) fd = uploads.EncryptStream(server_certificate.GetPublicKey(), config_lib.CONFIG["Client.private_key"], gzip_fd) response = self.grr_worker.http_manager.OpenServerEndpoint( u"/upload/", data=self.FileGenerator(fd), headers={ "x-grr-hmac": base64.b64encode(args.hmac), "x-grr-policy": base64.b64encode(args.policy), }, method="POST") if response.code != 200: raise IOError("Unable to upload %s" % args.pathspec.CollapsePath()) self.SendReply(file_fd.Stat())
def MakeClientAFF4Record(self): """Make a client in the data store.""" cert = self.ClientCertFromPrivateKey(self.client_private_key) client_cert = rdf_crypto.RDFX509Cert(cert.as_pem()) new_client = aff4.FACTORY.Create(client_cert.common_name, "VFSGRRClient", token=self.token) new_client.Set(new_client.Schema.CERT, client_cert) new_client.Close()
def setUp(self): """Set up communicator tests.""" super(HTTPClientTests, self).setUp() # These tests change the config so we preserve state. self.config_stubber = test_lib.PreserveConfig() self.config_stubber.Start() self.certificate = self.ClientCertFromPrivateKey( config_lib.CONFIG["Client.private_key"]).as_pem() self.server_serial_number = 0 self.server_private_key = config_lib.CONFIG["PrivateKeys.server_key"] self.server_certificate = config_lib.CONFIG["Frontend.certificate"] self.client_cn = rdf_crypto.RDFX509Cert(self.certificate).common_name # Make a new client self.CreateNewClientObject() # The housekeeper threads of the time based caches also call time.time and # interfere with some tests so we disable them here. utils.InterruptableThread.exit = True # The same also applies to the StatsCollector thread. stats.StatsCollector.exit = True # Make a client mock self.client = aff4.FACTORY.Create(self.client_cn, "VFSGRRClient", mode="rw", token=self.token) self.client.Set(self.client.Schema.CERT(self.certificate)) self.client.Flush() # Stop the client from actually processing anything self.out_queue_overrider = test_lib.ConfigOverrider( {"Client.max_out_queue": 0}) self.out_queue_overrider.Start() # And cache it in the server self.CreateNewServerCommunicator() self.urlopen_stubber = utils.Stubber(urllib2, "urlopen", self.UrlMock) self.urlopen_stubber.Start() self.sleep_stubber = utils.Stubber(time, "sleep", lambda x: None) self.sleep_stubber.Start() self.messages = [] ca_enroller.enrolment_cache.Flush() # Response to send back to clients. self.server_response = dict(session_id="aff4:/W:session", name="Echo", response_id=2)
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") req = X509.load_request_string(self.args.csr.pem) # Verify the CSR. This is not strictly necessary but doesn't harm either. if req.verify(req.get_pubkey()) != 1: raise flow.FlowError("CSR for client %s did not verify: %s" % (self.client_id, req.as_pem())) # Verify that the CN is of the correct form. The common name should refer # to a client URN. public_key = req.get_pubkey().get_rsa().pub()[1] self.cn = rdf_client.ClientURN.FromPublicKey(public_key) if self.cn != rdf_client.ClientURN(req.get_subject().CN): raise IOError( "CSR CN %s does not match public key %s." % (rdf_client.ClientURN(req.get_subject().CN), self.cn)) logging.info("Will sign CSR for: %s", self.cn) cert = self.MakeCert(self.cn, req) # 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. certificate_attribute = rdf_crypto.RDFX509Cert(cert.as_pem()) client.Set(client.Schema.CERT, certificate_attribute) 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", certificate_attribute.common_name) self.Log("Enrolled %s successfully", self.client_id)
def testExpiredTestCertificate(self): pem = open(os.path.join(self.base_path, "outdated_certificate")).read() certificate = rdf_crypto.RDFX509Cert(pem) exception_catcher = self.assertRaises(rdf_crypto.VerificationError) with exception_catcher: # We don't pass a proper key here, this will fail before it even touches # the key. certificate.Verify(None) self.assertIn("Certificate expired!", str(exception_catcher.exception))
def MakeCACert(private_key, common_name=u"grr", issuer_cn=u"grr_test", issuer_c=u"US"): """Generate a CA certificate. Args: private_key: The private key to use. common_name: Name for cert. issuer_cn: Name for issuer. issuer_c: Country for issuer. Returns: The certificate. """ public_key = private_key.GetPublicKey() builder = x509.CertificateBuilder() issuer = x509.Name([ x509.NameAttribute(oid.NameOID.COMMON_NAME, issuer_cn), x509.NameAttribute(oid.NameOID.COUNTRY_NAME, issuer_c) ]) subject = x509.Name( [x509.NameAttribute(oid.NameOID.COMMON_NAME, common_name)]) builder = builder.subject_name(subject) builder = builder.issuer_name(issuer) valid_from = rdfvalue.RDFDatetime.Now() - rdfvalue.Duration("1d") valid_until = rdfvalue.RDFDatetime.Now() + rdfvalue.Duration("3650d") builder = builder.not_valid_before(valid_from.AsDatetime()) builder = builder.not_valid_after(valid_until.AsDatetime()) builder = builder.serial_number(1) builder = builder.public_key(public_key.GetRawPublicKey()) builder = builder.add_extension( x509.BasicConstraints(ca=True, path_length=None), critical=True) builder = builder.add_extension( x509.SubjectKeyIdentifier.from_public_key(public_key.GetRawPublicKey()), critical=False) certificate = builder.sign( private_key=private_key.GetRawPrivateKey(), algorithm=hashes.SHA256(), backend=openssl.backend) return rdf_crypto.RDFX509Cert(certificate)
CERT = crypto.RDFX509Cert("""-----BEGIN CERTIFICATE----- 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 -----END CERTIFICATE-----""")