def sign(self, data, digestAlgorithm): """ Sign the data with this private key, returning a signature Blob. :param data: The input byte buffer. :type data: an array which implements the buffer protocol :param digestAlgorithm: The digest algorithm. :type digestAlgorithm: int from DigestAlgorithm :return: The signature Blob, or an isNull Blob if this private key is not initialized. :rtype: Blob :raises TpmPrivateKey.Error: For unrecognized digestAlgorithm or an error in signing. """ if digestAlgorithm != DigestAlgorithm.SHA256: raise TpmPrivateKey.Error( "TpmPrivateKey.sign: Unsupported digest algorithm") if self._keyType == KeyType.RSA: signer = self._privateKey.signer(padding.PKCS1v15(), hashes.SHA256()) elif self._keyType == KeyType.ECDSA: signer = self._privateKey.signer(ec.ECDSA(hashes.SHA256())) else: return Blob() signer.update(data) return Blob(bytearray(signer.finalize()), False)
def generateKeyPair(self, keyName, params): """ Generate a pair of asymmetric keys. :param Name keyName: The name of the key pair. :param KeyParams params: The parameters of the key. """ if self.doesKeyExist(keyName, KeyClass.PUBLIC): raise SecurityException("Public key already exists") if self.doesKeyExist(keyName, KeyClass.PRIVATE): raise SecurityException("Private key already exists") publicKeyDer = None privateKeyDer = None if params.getKeyType() == KeyType.RSA: key = RSA.generate(params.getKeySize()) publicKeyDer = key.publickey().exportKey(format='DER') privateKeyDer = key.exportKey(format='DER', pkcs=8) else: raise SecurityException("Unsupported key type") keyUri = keyName.toUri() publicKeyFilePath = self.nameTransform(keyUri, ".pub") privateKeyFilePath = self.nameTransform(keyUri, ".pri") with open(publicKeyFilePath, 'w') as keyFile: keyFile.write( Blob(base64.b64encode(publicKeyDer), False).toRawStr()) with open(privateKeyFilePath, 'w') as keyFile: keyFile.write( Blob(base64.b64encode(privateKeyDer), False).toRawStr()) os.chmod(publicKeyFilePath, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) os.chmod(privateKeyFilePath, stat.S_IRUSR)
def sign(self, data, keyName, digestAlgorithm=DigestAlgorithm.SHA256): """ Fetch the private key for keyName and sign the data, returning a signature Blob. :param data: The input byte buffer to sign. :type data: an array which implements the buffer protocol :param Name keyName: The name of the signing key. :param digestAlgorithm: (optional) the digest algorithm. If omitted, use DigestAlgorithm.SHA256. :type digestAlgorithm: int from DigestAlgorithm :return: The signature Blob. :rtype: Blob :raises SecurityException: if can't find the private key with keyName. """ if digestAlgorithm != DigestAlgorithm.SHA256: raise SecurityException( "MemoryPrivateKeyStorage.sign: Unsupported digest algorithm") # Find the private key. keyUri = keyName.toUri() if not keyUri in self._privateKeyStore: raise SecurityException( "MemoryPrivateKeyStorage: Cannot find private key " + keyUri) privateKey = self._privateKeyStore[keyUri] # Sign the hash of the data. if sys.version_info[0] == 2: # In Python 2.x, we need a str. Use Blob to convert data. data = Blob(data, False).toRawStr() signature = PKCS1_v1_5.new(privateKey.getPrivateKey()).sign( SHA256.new(data)) # Convert the string to a Blob. return Blob(bytearray(signature), False)
def encodeStateVector(stateVector, stateVectorKeys): """ Encode the stateVector as TLV. :param dict<str,int> stateVector: The state vector dictionary where the key is the member ID string and the value is the sequence number. :param list<str> stateVectorKeys: The key strings of stateVector, sorted in the order to be encoded. :return: A Blob containing the encoding. :rtype: Blob """ encoder = TlvEncoder(256) saveLength = len(encoder) # Encode backwards. for i in range(len(stateVectorKeys) - 1, -1, -1): saveLengthForEntry = len(encoder) encoder.writeNonNegativeIntegerTlv( StateVectorSync2018.TLV_StateVector_SequenceNumber, stateVector[stateVectorKeys[i]]) encoder.writeBlobTlv(StateVectorSync2018.TLV_StateVector_MemberId, Blob(stateVectorKeys[i]).buf()) encoder.writeTypeAndLength( StateVectorSync2018.TLV_StateVectorEntry, len(encoder) - saveLengthForEntry) encoder.writeTypeAndLength(StateVectorSync2018.TLV_StateVector, len(encoder) - saveLength) return Blob(encoder.getOutput(), False)
def _recomputeDigest(self): """ Digest the fields and set self._digest to the hex digest. """ sha256 = hashes.Hash(hashes.SHA256(), backend=default_backend()) number = bytearray(4) # Debug: sync-state.proto defines seq and session as uint64, but # the original ChronoChat-js only digests 32 bits. self._int32ToLittleEndian(self._sessionNo, number) sha256.update(Blob(number, False).toBytes()) self._int32ToLittleEndian(self._sequenceNo, number) sha256.update(Blob(number, False).toBytes()) sequenceDigest = sha256.finalize() sha256 = hashes.Hash(hashes.SHA256(), backend=default_backend()) # Use Blob to convert a string to UTF-8 if needed. sha256.update(Blob(self._dataPrefix, False).toBytes()) nameDigest = sha256.finalize() sha256 = hashes.Hash(hashes.SHA256(), backend=default_backend()) sha256.update(nameDigest) sha256.update(sequenceDigest) nodeDigest = sha256.finalize() # Use Blob to convert a str (Python 2) or bytes (Python 3) to hex. self._digest = Blob(nodeDigest, False).toHex()
def decodeData(self, data, input): """ Decode input as an NDN-TLV data packet, set the fields in the data object, and return the signed offsets. :param Data data: The Data object whose fields are updated. :param input: The array with the bytes to decode. :type input: An array type with int elements :return: A Tuple of (signedPortionBeginOffset, signedPortionEndOffset) where signedPortionBeginOffset is the offset in the encoding of the beginning of the signed portion, and signedPortionEndOffset is the offset in the encoding of the end of the signed portion. :rtype: (int, int) """ decoder = TlvDecoder(input) endOffset = decoder.readNestedTlvsStart(Tlv.Data) signedPortionBeginOffset = decoder.getOffset() self._decodeName(data.getName(), decoder) self._decodeMetaInfo(data.getMetaInfo(), decoder) data.setContent(Blob(decoder.readBlobTlv(Tlv.Content))) self._decodeSignatureInfo(data, decoder) signedPortionEndOffset = decoder.getOffset() data.getSignature().setSignature( Blob(decoder.readBlobTlv(Tlv.SignatureValue))) decoder.finishNestedTlvs(endOffset) return (signedPortionBeginOffset, signedPortionEndOffset)
def signWithSha256(self, data, wireFormat = None): """ Wire encode the Data object, digest it and set its SignatureInfo to a DigestSha256. :param Data data: The Data object to be signed. This updates its signature and wireEncoding. :param wireFormat: (optional) A WireFormat object used to encode the input. If omitted, use WireFormat.getDefaultWireFormat(). :type wireFormat: A subclass of WireFormat """ if wireFormat == None: # Don't use a default argument since getDefaultWireFormat can change. wireFormat = WireFormat.getDefaultWireFormat() data.setSignature(DigestSha256Signature()) # Encode once to get the signed portion. encoding = data.wireEncode(wireFormat) # Get the bytes to sign. signedPortion = encoding.toSignedBuffer() if sys.version_info[0] == 2: # In Python 2.x, we need a str. Use Blob to convert signedPortion. signedPortion = Blob(signedPortion, False).toRawStr() # Digest and set the signature. data.getSignature().setSignature(Blob(SHA256.new(signedPortion).digest())) # Encode again to include the signature. data.wireEncode(wireFormat)
def _onData(self, interest, data): """ Process Sync Data. """ if not self._enabled: # Ignore callbacks after the application calls shutdown(). return logging.getLogger(__name__).info( "Sync ContentObject received in callback") logging.getLogger(__name__).info("name: %s", data.getName().toUri()) # TODO: Check if this works in Python 3. tempContent = SyncStateMsg() #pylint: disable=E1103 tempContent.ParseFromString(data.getContent().toBytes()) #pylint: enable=E1103 content = getattr(tempContent, "ss") if self._digestTree.getRoot() == "00": isRecovery = True #processing initial sync data self._initialOndata(content) else: self._update(content) if (interest.getName().size() == self._applicationBroadcastPrefix.size() + 2): # Assume this is a recovery interest. isRecovery = True else: isRecovery = False # Send the interests to fetch the application data. syncStates = [] for i in range(len(content)): syncState = content[i] # Only report UPDATE sync states. if syncState.type == SyncState_UPDATE: if len(syncState.application_info) > 0: applicationInfo = Blob(syncState.application_info, True) else: applicationInfo = Blob() syncStates.append( self.SyncState(syncState.name, syncState.seqno.session, syncState.seqno.seq, applicationInfo)) try: self._onReceivedSyncState(syncStates, isRecovery) except: logging.exception("Error in onReceivedSyncState") name = Name(self._applicationBroadcastPrefix) name.append(self._digestTree.getRoot()) syncInterest = Interest(name) syncInterest.setInterestLifetimeMilliseconds(self._syncLifetime) self._face.expressInterest(syncInterest, self._onData, self._syncTimeout) logging.getLogger(__name__).info("Syncinterest expressed:") logging.getLogger(__name__).info("%s", name.toUri())
def clear(self): """ Set all the fields to indicate unspecified values. """ self._algorithmType = None self._keyLocator = KeyLocator() self._initialVector = Blob() self._payload = Blob() self._payloadKey = Blob()
def __init__(self, value = None): if type(value) is Name.Component: # Use the existing Blob in the other Component. self._value = value._value elif value == None: self._value = Blob([]) else: # Blob will make a copy. self._value = value if isinstance(value, Blob) else Blob(value)
def _registerPrefixHelper(self, registeredPrefixId, prefix, onInterest, onRegisterFailed, flags, wireFormat): """ Do the work of registerPrefix to register with NDNx once we have an ndndId_. :param int registeredPrefixId: The _RegisteredPrefix.getNextRegisteredPrefixId() which registerPrefix got so it could return it to the caller. If this is 0, then don't add to registeredPrefixTable_ (assuming it has already been done). """ # Create a ForwardingEntry. # Note: ndnd ignores any freshness that is larger than 3600 seconds and # sets 300 seconds instead. To register "forever", (=2000000000 sec), # the freshness period must be omitted. forwardingEntry = ForwardingEntry() forwardingEntry.setAction("selfreg") forwardingEntry.setPrefix(prefix) forwardingEntry.setForwardingFlags(flags) content = forwardingEntry.wireEncode(wireFormat) # Set the ForwardingEntry as the content of a Data packet and sign. data = Data() data.setContent(content) # Set the name to a random value so that each request is unique. nonce = bytearray(4) for i in range(len(nonce)): nonce[i] = _systemRandom.randint(0, 0xff) data.getName().append(nonce) # The ndnd ignores the signature, so set to blank values. data.getSignature().getKeyLocator().setType( KeyLocatorType.KEY_LOCATOR_DIGEST) data.getSignature().getKeyLocator().setKeyData( Blob(bytearray(32), False)) data.getSignature().setSignature(Blob(bytearray(128), False)) encodedData = data.wireEncode(wireFormat) # Create an interest where the name has the encoded Data packet. interestName = Name().append("ndnx").append( self._ndndId).append("selfreg").append(encodedData) interest = Interest(interestName) interest.setInterestLifetimeMilliseconds(4000.0) interest.setScope(1) encodedInterest = interest.wireEncode(wireFormat) if registeredPrefixId != 0: # Save the onInterest callback and send the registration interest. self._registeredPrefixTable.append( Node._RegisteredPrefix(registeredPrefixId, prefix, onInterest)) response = Node._RegisterResponse(self, prefix, onInterest, onRegisterFailed, flags, wireFormat, False) self.expressInterest(interest, response.onData, response.onTimeout, wireFormat)
def __init__(self, algorithmType, initialVectorLength=None): self._algorithmType = algorithmType if initialVectorLength != None and initialVectorLength > 0: initialVector = bytearray(initialVectorLength) for i in range(initialVectorLength): initialVector[i] = _systemRandom.randint(0, 0xff) self._initialVector = Blob(initialVector, False) else: self._initialVector = Blob()
def sign(self, data, keyName, digestAlgorithm=DigestAlgorithm.SHA256): """ Fetch the private key for keyName and sign the data, returning a signature Blob. :param data: Pointer the input byte buffer to sign. :type data: An array type with int elements :param Name keyName: The name of the signing key. :param digestAlgorithm: (optional) the digest algorithm. If omitted, use DigestAlgorithm.SHA256. :type digestAlgorithm: int from DigestAlgorithm :return: The signature Blob. :rtype: Blob """ keyURI = keyName.toUri() if not self.doesKeyExist(keyName, KeyClass.PRIVATE): raise SecurityException( "FilePrivateKeyStorage.sign: private key doesn't exist") if digestAlgorithm != DigestAlgorithm.SHA256: raise SecurityException( "FilePrivateKeyStorage.sign: Unsupported digest algorithm") # Read the private key. base64Content = None with open(self.nameTransform(keyURI, ".pri")) as keyFile: base64Content = keyFile.read() der = Blob(base64.b64decode(base64Content), False) # Decode the PKCS #8 key to get the algorithm OID. parsedNode = DerNode.parse(der.buf(), 0) pkcs8Children = parsedNode.getChildren() algorithmIdChildren = DerNode.getSequence(pkcs8Children, 1).getChildren() oidString = algorithmIdChildren[0].toVal() privateKey = serialization.load_der_private_key( der.toBytes(), password=None, backend=default_backend()) # Sign the data. data = Blob(data, False).toBytes() if (oidString == PublicKey.RSA_ENCRYPTION_OID or oidString == PublicKey.EC_ENCRYPTION_OID): if oidString == PublicKey.RSA_ENCRYPTION_OID: signer = privateKey.signer(padding.PKCS1v15(), hashes.SHA256()) else: signer = privateKey.signer(ec.ECDSA(hashes.SHA256())) signer.update(data) signature = signer.finalize() return Blob(bytearray(signature), False) else: raise SecurityException( "FilePrivateKeyStorage.sign: Unrecognized private key type")
def addMember(self, memberCertificate): """ Authorize a member identified by memberCertificate to decrypt data under the policy. :param CertificateV2 memberCertificate: The certificate that identifies the member to authorize. :return: The published KDK Data packet. :rtype: Data """ kdkName = Name(self._nacKey.getIdentityName()) kdkName.append(EncryptorV2.NAME_COMPONENT_KDK).append( # key-id self._nacKey.getName().get(-1)).append( EncryptorV2.NAME_COMPONENT_ENCRYPTED_BY).append( memberCertificate.getKeyName()) secretLength = 32 secret = bytearray(secretLength) for i in range(secretLength): secret[i] = _systemRandom.randint(0, 0xff) # To be compatible with OpenSSL which uses a null-terminated string, # replace each 0 with 1. And to be compatible with the Java security # library which interprets the secret as a char array converted to UTF8, # limit each byte to the ASCII range 1 to 127. for i in range(secretLength): if secret[i] == 0: secret[i] = 1 secret[i] &= 0x7f kdkSafeBag = self._keyChain.exportSafeBag( self._nacKey.getDefaultCertificate(), Blob(secret, False).toBytes()) memberKey = PublicKey(memberCertificate.getPublicKey()) encryptedContent = EncryptedContent() encryptedContent.setPayload(kdkSafeBag.wireEncode()) encryptedContent.setPayloadKey( memberKey.encrypt( Blob(secret, False).toBytes(), EncryptAlgorithmType.RsaOaep)) kdkData = Data(kdkName) kdkData.setContent(encryptedContent.wireEncodeV2()) # FreshnessPeriod can serve as a soft access control for revoking access. kdkData.getMetaInfo().setFreshnessPeriod( AccessManagerV2.DEFAULT_KDK_FRESHNESS_PERIOD_MS) self._keyChain.sign(kdkData, SigningInfo(self._identity)) self._storage.insert(kdkData) return kdkData
def generateKeyPair(self, keyName, params): """ Generate a pair of asymmetric keys. :param Name keyName: The name of the key pair. :param KeyParams params: The parameters of the key. """ if self.doesKeyExist(keyName, KeyClass.PUBLIC): raise SecurityException("Public key already exists") if self.doesKeyExist(keyName, KeyClass.PRIVATE): raise SecurityException("Private key already exists") publicKeyDer = None privateKeyDer = None if (params.getKeyType() == KeyType.RSA or params.getKeyType() == KeyType.ECDSA): if params.getKeyType() == KeyType.RSA: privateKey = rsa.generate_private_key( public_exponent=65537, key_size=params.getKeySize(), backend=default_backend()) else: privateKey = ec.generate_private_key( PrivateKeyStorage.getEcCurve(params.getKeySize()), default_backend()) publicKeyDer = privateKey.public_key().public_bytes( encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo) privateKeyDer = privateKey.private_bytes( encoding=serialization.Encoding.DER, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption()) else: raise SecurityException("Unsupported key type") keyUri = keyName.toUri() keyFilePathNoExtension = self.maintainMapping(keyUri) publicKeyFilePath = keyFilePathNoExtension + ".pub" privateKeyFilePath = keyFilePathNoExtension + ".pri" with open(publicKeyFilePath, 'w') as keyFile: keyFile.write( Blob(base64.b64encode(publicKeyDer), False).toRawStr()) with open(privateKeyFilePath, 'w') as keyFile: keyFile.write( Blob(base64.b64encode(privateKeyDer), False).toRawStr()) os.chmod(publicKeyFilePath, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH) os.chmod(privateKeyFilePath, stat.S_IRUSR)
def __init__(self, value=None): if isinstance(value, Interest): # Copy the values. self._name = ChangeCounter(Name(value.getName())) self._minSuffixComponents = value._minSuffixComponents self._maxSuffixComponents = value._maxSuffixComponents self._didSetCanBePrefix = value._didSetCanBePrefix self._keyLocator = ChangeCounter(KeyLocator(value.getKeyLocator())) self._exclude = ChangeCounter(Exclude(value.getExclude())) self._childSelector = value._childSelector self._mustBeFresh = value._mustBeFresh self._nonce = value.getNonce() self._interestLifetimeMilliseconds = value._interestLifetimeMilliseconds self._forwardingHint = ChangeCounter( DelegationSet(value.getForwardingHint())) self._applicationParameters = value._applicationParameters self._linkWireEncoding = value._linkWireEncoding self._linkWireEncodingFormat = value._linkWireEncodingFormat self._link = ChangeCounter(None) if value._link.get() != None: self._link.set(Link(value._link.get())) self._selectedDelegationIndex = value._selectedDelegationIndex self._defaultWireEncoding = value.getDefaultWireEncoding() self._defaultWireEncodingFormat = value._defaultWireEncodingFormat else: self._name = ChangeCounter(Name(value)) self._minSuffixComponents = None self._maxSuffixComponents = None if Interest._defaultCanBePrefix else 1 # _didSetCanBePrefix is True if the app already called setDefaultCanBePrefix(). self._didSetCanBePrefix = Interest._didSetDefaultCanBePrefix self._keyLocator = ChangeCounter(KeyLocator()) self._exclude = ChangeCounter(Exclude()) self._childSelector = None self._mustBeFresh = False self._nonce = Blob() self._interestLifetimeMilliseconds = None self._forwardingHint = ChangeCounter(DelegationSet()) self._applicationParameters = Blob() self._linkWireEncoding = Blob() self._linkWireEncodingFormat = None self._link = ChangeCounter(None) self._selectedDelegationIndex = None self._defaultWireEncoding = SignedBlob() self._defaultWireEncodingFormat = None self._getNonceChangeCount = 0 self._getDefaultWireEncodingChangeCount = 0 self._changeCount = 0 self._lpPacket = None
def __init__(self, value = None): if type(value) is Name.Component: # Copy constructor. Use the existing Blob in the other Component. self._value = value._value self._type = value._type return if value == None: self._value = Blob([]) else: # Blob will make a copy. self._value = value if isinstance(value, Blob) else Blob(value) self._type = Name.Component.ComponentType.GENERIC
def encodeControlParameters(self, controlParameters): """ Encode controlParameters and return the encoding. :param controlParameters: The ControlParameters object to encode. :type controlParameters: ControlParameters :return: A Blob containing the encoding. :rtype: Blob """ encoder = TlvEncoder(256) saveLength = len(encoder) # Encode backwards. encoder.writeOptionalNonNegativeIntegerTlvFromFloat( Tlv.ControlParameters_ExpirationPeriod, controlParameters.getExpirationPeriod()) if controlParameters.getStrategy().size() > 0: strategySaveLength = len(encoder) self._encodeName(controlParameters.getStrategy(), encoder) encoder.writeTypeAndLength(Tlv.ControlParameters_Strategy, len(encoder) - strategySaveLength) flags = controlParameters.getForwardingFlags().getNfdForwardingFlags() if (flags != ForwardingFlags().getNfdForwardingFlags()): # The flags are not the default value. encoder.writeNonNegativeIntegerTlv(Tlv.ControlParameters_Flags, flags) encoder.writeOptionalNonNegativeIntegerTlv(Tlv.ControlParameters_Cost, controlParameters.getCost()) encoder.writeOptionalNonNegativeIntegerTlv( Tlv.ControlParameters_Origin, controlParameters.getOrigin()) encoder.writeOptionalNonNegativeIntegerTlv( Tlv.ControlParameters_LocalControlFeature, controlParameters.getLocalControlFeature()) if len(controlParameters.getUri()) != 0: encoder.writeBlobTlv(Tlv.ControlParameters_Uri, Blob(controlParameters.getUri()).buf()) encoder.writeOptionalNonNegativeIntegerTlv( Tlv.ControlParameters_FaceId, controlParameters.getFaceId()) if controlParameters.getName() != None: self._encodeName(controlParameters.getName(), encoder) encoder.writeTypeAndLength(Tlv.ControlParameters_ControlParameters, len(encoder) - saveLength) return Blob(encoder.getOutput(), False)
def __init__(self, value=None): if type(value) is Interest: # Copy the values. self._name = ChangeCounter(Name(value.getName())) self._minSuffixComponents = value._minSuffixComponents self._maxSuffixComponents = value._maxSuffixComponents self._keyLocator = ChangeCounter(KeyLocator(value.getKeyLocator())) self._exclude = ChangeCounter(Exclude(value.getExclude())) self._childSelector = value._childSelector self._mustBeFresh = value._mustBeFresh self._nonce = value.getNonce() self._interestLifetimeMilliseconds = value._interestLifetimeMilliseconds self._forwardingHint = ChangeCounter( DelegationSet(value.getForwardingHint())) self._linkWireEncoding = value._linkWireEncoding self._linkWireEncodingFormat = value._linkWireEncodingFormat self._link = ChangeCounter(None) if value._link.get() != None: self._link.set(Link(value._link.get())) self._selectedDelegationIndex = value._selectedDelegationIndex self._defaultWireEncoding = value.getDefaultWireEncoding() self._defaultWireEncodingFormat = value._defaultWireEncodingFormat self._content = value._content else: self._name = ChangeCounter( Name(value) if type(value) is Name else Name()) self._minSuffixComponents = None self._maxSuffixComponents = None self._keyLocator = ChangeCounter(KeyLocator()) self._exclude = ChangeCounter(Exclude()) self._childSelector = None self._mustBeFresh = True self._nonce = Blob() self._interestLifetimeMilliseconds = None self._forwardingHint = ChangeCounter(DelegationSet()) self._linkWireEncoding = Blob() self._linkWireEncodingFormat = None self._link = ChangeCounter(None) self._selectedDelegationIndex = None self._defaultWireEncoding = SignedBlob() self._defaultWireEncodingFormat = None self._content = Blob() self._getNonceChangeCount = 0 self._getDefaultWireEncodingChangeCount = 0 self._changeCount = 0 self._lpPacket = None
def loadPkcs1(self, encoding, keyType=None): """ Load the unencrypted private key from a buffer with the PKCS #1 encoding. This replaces any existing private key in this object. :param encoding: The byte buffer with the private key encoding. :type encoding: str, or an array type with int elements which is converted to str :param KeyType keyType: (optional) The KeyType, such as KeyType.RSA. If omitted or None, then partially decode the private key to determine the key type. :raises TpmPrivateKey.Error: For errors decoding the key. """ if keyType == None: # Try to determine the key type. try: parsedNode = DerNode.parse(Blob(encoding, False).buf()) children = parsedNode.getChildren() # An RsaPrivateKey has integer version 0 and 8 integers. if (len(children) == 9 and isinstance(children[0], DerInteger) and children[0].toVal() == 0 and isinstance(children[1], DerInteger) and isinstance(children[2], DerInteger) and isinstance(children[3], DerInteger) and isinstance(children[4], DerInteger) and isinstance(children[5], DerInteger) and isinstance(children[6], DerInteger) and isinstance(children[7], DerInteger) and isinstance(children[8], DerInteger)): keyType = KeyType.RSA else: # Assume it is an EC key. Try decoding it below. keyType = KeyType.ECDSA except DerDecodingException: # Assume it is an EC key. Try decoding it below. keyType = KeyType.ECDSA if keyType == KeyType.ECDSA or keyType == KeyType.RSA: # serialization can load PKCS #1 directly. self._privateKey = serialization.load_der_private_key( Blob(encoding, False).toBytes(), password=None, backend=default_backend()) else: raise TpmPrivateKey.Error("loadPkcs1: Unrecognized keyType: " + str(keyType)) self._keyType = keyType
def encode(self): """ Encode this IBLT to a Blob. This encodes this hash table from a uint32_t array to a uint8_t array. We create a uin8_t array 12 times the size of the uint32_t array. We put the first count in the first 4 cells, keySum in the next 4, and keyCheck in the next 4. We repeat for all the other cells of the hash table. Then we append this uint8_t array to the name. :return: The encoded Blob. :rtype: Blob """ nEntries = len(self._hashTable) # hard coding unitSize = int((32 * 3) / 8) tableSize = unitSize * nEntries table = [0] * tableSize for i in range(nEntries): entry = self._hashTable[i] # table[i*12], table[i*12+1], table[i*12+2], table[i*12+3] --> hashTable[i]._count table[(i * unitSize)] = 0xFF & entry._count table[(i * unitSize) + 1] = 0xFF & (entry._count >> 8) table[(i * unitSize) + 2] = 0xFF & (entry._count >> 16) table[(i * unitSize) + 3] = 0xFF & (entry._count >> 24) # table[i*12+4], table[i*12+5], table[i*12+6], table[i*12+7] --> hashTable[i]._keySum table[(i * unitSize) + 4] = 0xFF & entry._keySum table[(i * unitSize) + 5] = 0xFF & (entry._keySum >> 8) table[(i * unitSize) + 6] = 0xFF & (entry._keySum >> 16) table[(i * unitSize) + 7] = 0xFF & (entry._keySum >> 24) # table[i*12+8], table[i*12+9], table[i*12+10], table[i*12+11] --> hashTable[i]._keyCheck table[(i * unitSize) + 8] = 0xFF & entry._keyCheck table[(i * unitSize) + 9] = 0xFF & (entry._keyCheck >> 8) table[(i * unitSize) + 10] = 0xFF & (entry._keyCheck >> 16) table[(i * unitSize) + 11] = 0xFF & (entry._keyCheck >> 24) Z_BEST_COMPRESSION = 9 # Use Blob to convert an array to bytes on both Python 2 and 3. compressedBytes = zlib.compress( Blob(table, False).toBytes(), Z_BEST_COMPRESSION) return Blob(compressedBytes, False)