def parse(self, p): p.startLengthCheck(3) if self.certificateType == CertificateType.x509: chainLength = p.get(3) index = 0 certificate_list = [] while index != chainLength: certBytes = p.getVarBytes(3) x509 = X509() x509.parseBinary(certBytes) certificate_list.append(x509) index += len(certBytes)+3 if certificate_list: self.certChain = X509CertChain(certificate_list) elif self.certificateType == CertificateType.cryptoID: s = bytesToString(p.getVarBytes(2)) if s: try: import cryptoIDlib.CertChain except ImportError: raise SyntaxError(\ "cryptoID cert chain received, cryptoIDlib not present") self.certChain = cryptoIDlib.CertChain.CertChain().parse(s) else: raise AssertionError() p.stopLengthCheck() return self
def _secure_state(self): """ creates a new X509 certificate and state key and sets up the state keys requires that the device list be instantiated and non-empty will set the values for state_keys, state_key, cert_pem, and privkey_pem """ # make a new keypair for the namespace pkey = crypto.PKey() pkey.generate_key(crypto.TYPE_RSA, 1024) x509 = X509(self.id, pkey, self.conf['aws_conf'][AWS_USERNAME], self.conf['user_conf']['country'], self.conf['user_conf']['state'], self.conf['user_conf']['city']) x509.forge_certificate(False) x509.sign_certificate(None) self.x509 = x509 rec = x509.get_PEM_certificate() self.cert_pem = rec[0] self.privkey_pem = rec[1] # set up the state keys self.state_key = Random.new().read(32) self.state_keys = {} for dev in self.dev_list: self.state_keys[dev.dev_id] = b64encode( encrypt_with_cert(dev.cert_pem, self.state_key)) self._secure_metadata()
def get_X509(self, safe_user, privkey_pem=None): return X509( self.dev_name, crypto.load_privatekey(crypto.FILETYPE_PEM, privkey_pem) if privkey_pem else None, safe_user.conf['user_conf']['name'], safe_user.conf['user_conf']['country'], safe_user.conf['user_conf']['state'], safe_user.conf['user_conf']['city'], crypto.load_certificate(crypto.FILETYPE_PEM, self.cert_pem))
def create_device_certificates(conf, signer=None): """ creates a X509 certificate/private key pair returns: (cert_pem, privkey_pem) """ pkey = crypto.PKey() pkey.generate_key(crypto.TYPE_RSA, 1024) x509 = X509(conf['dev_conf']['dev_name'], pkey, conf['user_conf']['name'], conf['user_conf']['country'], conf['user_conf']['state'], conf['user_conf']['city']) x509.forge_certificate(False) x509.sign_certificate(signer) rec = x509.get_PEM_certificate() cert_pem = rec[0] key_pem = rec[1] return (cert_pem, key_pem)
def next(self): """Iterates and returns the next L{tlslite.X509.X509} certificate in data. @rtype tlslite.X509.X509 """ self.index = self.data.find(self._CERTIFICATE_HEADER, self.index) if self.index == -1: raise StopIteration end = self.data.find(self._CERTIFICATE_FOOTER, self.index) if end == -1: raise StopIteration certStr = self.data[self.index + len(self._CERTIFICATE_HEADER):end] self.index = end + len(self._CERTIFICATE_FOOTER) bytes = cryptomath.base64ToBytes(certStr) return X509().parseBinary(bytes)
def _reconcile_state(self): """ updates the in-memory representation of the state object to represent the remote serialization. called on initialization or any time a conditional write fails. """ namespace_table = self.dynamo.get_table('namespaces') try: self.serialized = namespace_table.get_item(hash_key=self.id) except DynamoDBKeyNotFoundError as e: self._initialize_state(namespace_table) return # Get the state_key self.state_keys = json.loads(self.serialized['state_keys']) if str(self.dev.dev_id) not in self.state_keys: raise KeyError("Local device ID not found in keys") else: state_key = b64decode(self.state_keys[str(self.dev.dev_id)]) self.state_key = self.dev_kc.decrypt(state_key) # Get the namespace keys self.cert_pem = AES_decrypt(self.serialized['cert_pem'], self.state_key) self.privkey_pem = AES_decrypt(self.serialized['privkey_pem'], self.state_key) self.x509 = X509( None, crypto.load_privatekey(crypto.FILETYPE_PEM, self.privkey_pem), self.conf['user_conf']['name'], self.conf['user_conf']['country'], self.conf['user_conf']['state'], self.conf['user_conf']['city'], crypto.load_certificate(crypto.FILETYPE_PEM, self.cert_pem)) # Check the logs self.logs = self._read_logs() logs = json.loads(self.serialized['logs']) for i, sig in enumerate(reversed(self.logs)): if logs[-(i + 1)] != sig: raise AccountCompromisedException( "It appears that the SafeUser state has been forked!") # verify the state signature to_be_verified = json.dumps([ key for key, value in sorted(self.serialized.items()) if key in SafeUser.STATE_ATTRS ]) if logs and not verify_signature(self.cert_pem, to_be_verified, logs[0]): raise AccountCompromisedException( "It appears that the SafeUser state has not been properly signed!" ) self.logs = logs self._write_logs() self.old_identities = json.loads( AES_decrypt(self.serialized['old_identities'], self.state_key)) # Get the peer ns list dec_ns_list = AES_decrypt(self.serialized['ns_list'], self.state_key) if hasattr(self, 'ns_list'): self._peer_list.update_from_serialization(dec_ns_list) else: self._peer_list = SafeList(dec_ns_list, SafePeer) # Get the device list dec_dev_list = AES_decrypt(self.serialized['dev_list'], self.state_key) if hasattr(self, 'dev_list'): self._dev_list.update_from_serialization(dec_dev_list) else: self._dev_list = SafeList(dec_dev_list, SafeDevice) # get the uid self.uid = AES_decrypt(self.serialized['uid'], self.state_key) # get the metadata self.metadata_keys = json.loads(self.serialized['metadata_keys']) index = b64encode(hashlib.sha256(self.cert_pem + self.uid).digest()) if index not in self.metadata_keys: raise KeyError( "Namespace does not have access to its own metadata!") else: metadata_key = b64decode(self.metadata_keys[index]) self.metadata_key = decrypt_with_privkey(self.privkey_pem, metadata_key) self.metadata = json.loads( AES_decrypt(self.serialized['metadata'], self.metadata_key)) # drain the message queue and update keys accordningly if self._receive_messages() or not self._validate_device_signature(): self._reconcile_state()