Exemplo n.º 1
0
    def _makeSelfSignedCertificate(keyName, privateKeyBag, publicKeyEncoding,
                                   password, digestAlgorithm, wireFormat):
        certificate = CertificateV2()

        # Set the name.
        now = Common.getNowMilliseconds()
        certificateName = Name(keyName)
        certificateName.append("self").appendVersion(int(now))
        certificate.setName(certificateName)

        # Set the MetaInfo.
        certificate.getMetaInfo().setType(ContentType.KEY)
        # Set a one-hour freshness period.
        certificate.getMetaInfo().setFreshnessPeriod(3600 * 1000.0)

        # Set the content.
        publicKey = PublicKey(publicKeyEncoding)
        certificate.setContent(publicKey.getKeyDer())

        # Create a temporary in-memory Tpm and import the private key.
        tpm = Tpm("", "", TpmBackEndMemory())
        tpm._importPrivateKey(keyName, privateKeyBag.toBytes(), password)

        # Set the signature info.
        if publicKey.getKeyType() == KeyType.RSA:
            certificate.setSignature(Sha256WithRsaSignature())
        elif publicKey.getKeyType() == KeyType.EC:
            certificate.setSignature(Sha256WithEcdsaSignature())
        else:
            raise ValueError("Unsupported key type")
        signatureInfo = certificate.getSignature()
        KeyLocator.getFromSignature(signatureInfo).setType(
            KeyLocatorType.KEYNAME)
        KeyLocator.getFromSignature(signatureInfo).setKeyName(keyName)

        # Set a 20-year validity period.
        ValidityPeriod.getFromSignature(signatureInfo).setPeriod(
            now, now + 20 * 365 * 24 * 3600 * 1000.0)

        # Encode once to get the signed portion.
        encoding = certificate.wireEncode(wireFormat)
        signatureBytes = tpm.sign(encoding.toSignedBytes(), keyName,
                                  digestAlgorithm)
        signatureInfo.setSignature(signatureBytes)

        # Encode again to include the signature.
        certificate.wireEncode(wireFormat)

        return certificate
Exemplo n.º 2
0
    def _makeSelfSignedCertificate(
      keyName, privateKeyBag, publicKeyEncoding, password, digestAlgorithm,
      wireFormat):
        certificate = CertificateV2()

        # Set the name.
        now = Common.getNowMilliseconds()
        certificateName = Name(keyName)
        certificateName.append("self").appendVersion(int(now))
        certificate.setName(certificateName)

        # Set the MetaInfo.
        certificate.getMetaInfo().setType(ContentType.KEY)
        # Set a one-hour freshness period.
        certificate.getMetaInfo().setFreshnessPeriod(3600 * 1000.0)

        # Set the content.
        publicKey = PublicKey(publicKeyEncoding)
        certificate.setContent(publicKey.getKeyDer())

        # Create a temporary in-memory Tpm and import the private key.
        tpm = Tpm("", "", TpmBackEndMemory())
        tpm._importPrivateKey(keyName, privateKeyBag.toBytes(), password)

        # Set the signature info.
        if publicKey.getKeyType() == KeyType.RSA:
            certificate.setSignature(Sha256WithRsaSignature())
        elif publicKey.getKeyType() == KeyType.EC:
            certificate.setSignature(Sha256WithEcdsaSignature())
        else:
            raise ValueError("Unsupported key type")
        signatureInfo = certificate.getSignature()
        KeyLocator.getFromSignature(signatureInfo).setType(KeyLocatorType.KEYNAME)
        KeyLocator.getFromSignature(signatureInfo).setKeyName(keyName)

        # Set a 20-year validity period.
        ValidityPeriod.getFromSignature(signatureInfo).setPeriod(
          now, now + 20 * 365 * 24 * 3600 * 1000.0)

        # Encode once to get the signed portion.
        encoding = certificate.wireEncode(wireFormat)
        signatureBytes = tpm.sign(encoding.toSignedBytes(), keyName,
          digestAlgorithm)
        signatureInfo.setSignature(signatureBytes)

        # Encode again to include the signature.
        certificate.wireEncode(wireFormat)

        return certificate
Exemplo n.º 3
0
class Certificate(Data):
    epochStart = datetime(1970,1,1)
    def __init__(self, other=None):
        """
        Create a new certificate, optionally copying the
        contents of another Data object.
        :param other: (optional) A Data packet to copy the content from
        :type other: Data
        """
        super(Certificate,self).__init__(other)
        self._subjectDescriptionList = []
        self._extensionList = []
        if isinstance(other, Data):
            self.decode()
        else:
            self._notBefore = 1e37
            self._notAfter = -1e37
            self._publicKey = PublicKey()

    def isTooEarly(self):
        """
        Check if the certificate start date is in the future
        :return: True if the certificate cannot be used yet
        :rtype: boolean
        """

        secondsSince1970 = (datetime.now() - self.epochStart).total_seconds
        if secondsSince1970 < self.getNotBefore()/1000:
            return True
        return False

    def isTooLate(self):
        """
        Check if the certificate end date is in the past
        :return: True if the certificate has expired
        :rtype: boolean
        """
        secondsSince1970 = (datetime.now() - self.epochStart).total_seconds
        if secondsSince1970 > self.getNotAfter()/1000:
            return True
        return False

    def isInValidityPeriod(self, time):
        return self.getSignature().getValidityPeriod().isValid(time)

    def __str__(self):
        s = "Certificate name:\n"
        s += "  "+self.getName().toUri()+"\n"
        s += "Validity:\n"

        dateFormat = "%Y%m%dT%H%M%S"
        notBeforeStr = datetime.utcfromtimestamp(self.getNotBefore()/1000).strftime(dateFormat)
        notAfterStr = datetime.utcfromtimestamp(self.getNotAfter()/1000).strftime(dateFormat)

        s += "  NotBefore: " + notBeforeStr+"\n"
        s += "  NotAfter: " + notAfterStr + "\n"
        for sd in self._subjectDescriptionList:
            s += "Subject Description:\n"
            s += "  " + str(sd.getOid()) + ": " + sd.getValue().toRawStr() + "\n"

        s += "Public key bits:\n"
        keyDer = self.getPublicKeyDer()
        encodedKey = base64.b64encode(keyDer.toBytes())
        for idx in range(0, len(encodedKey), 64):
            # Use Blob to convert to a str.
            s += Blob(encodedKey[idx:idx+64], False).toRawStr() + "\n"


        if len(self._extensionList) > 0:
            s += "Extensions:\n"
            for ext in self._extensionList:
                s += "  OID: "+ext.getOid()+"\n"
                s += "  Is critical: " + ('Y' if ext.isCritical() else 'N') + "\n"

                s += "  Value: " + str(ext.getValue()).encode('hex') + "\n"

        return s


    def addSubjectDescription(self, descr):
        """
        Add a subject description field to the certificate.
        :param descr: The CertificateSubjectDescription object to add
        """
        self._subjectDescriptionList.append(descr)

    def addExtension(self, ext):
        """
        Add an extension field to the certificate.
        :param ext: Th CertificateExtension object to add
        """
        self._extensionList.append(ext)

    def toDer(self):
        """
        Encode the certificate fields in DER format.
        :return: The DER encoded contents of the certificate.
        :rtype: DerNode
        """
        root = DerSequence()
        validity = DerSequence()
        notBefore = DerGeneralizedTime(self.getNotBefore())
        notAfter = DerGeneralizedTime(self.getNotAfter())

        validity.addChild(notBefore)
        validity.addChild(notAfter)

        root.addChild(validity)

        subjectList = DerSequence()
        for sd in self._subjectDescriptionList:
            child = sd.toDer()
            subjectList.addChild(child)

        root.addChild(subjectList)
        root.addChild(self._publicKey.toDer())

        if (len(self._extensionList) > 0):
            extnList = DerSequence()
            for ext in self._extensionList:
                child = ext.toDer()
                extnList.addChild(child)
            root.addChild(extnList)

        return root

    def encode(self):
        """
            Encode the contents of the certificate in DER format and set the
            Content and MetaInfo fields.
        """
        root = self.toDer()
        outVal = root.encode()
        self.setContent(Blob(outVal))
        self.getMetaInfo().setType(ContentType.KEY)

    def decode(self):
        """
        Populates the fields by decoding DER data from the Content.
        """
        root = DerNode.parse(self.getContent())

        # we need to ensure that there are:
        #   validity (notBefore, notAfter)
        #   subject list
        #   public key
        #   (optional) extension list

        rootChildren = root.getChildren()
        # 1st: validity info
        validityChildren = DerNode.getSequence(rootChildren, 0).getChildren()
        self._notBefore = validityChildren[0].toVal()
        self._notAfter = validityChildren[1].toVal()

        # 2nd: subjectList
        subjectChildren = DerNode.getSequence(rootChildren, 1).getChildren()
        for sd in subjectChildren:
            descriptionChildren = sd.getChildren()
            oidStr = descriptionChildren[0].toVal()
            value = descriptionChildren[1].toVal()

            subjectDesc = CertificateSubjectDescription(oidStr, value)
            self.addSubjectDescription(subjectDesc)

        # 3rd: public key
        publicKeyInfo = rootChildren[2].encode()
        self._publicKey = PublicKey(publicKeyInfo)

        if len(rootChildren) > 3:
            extensionChildren = DerNode.getSequence(rootChildren, 3).getChildren()
            for extInfo in extensionChildren:
                children = extInfo.getChildren()
                oidStr = children[0].toVal()
                isCritical = children[1].toVal()
                value = children[2].toVal()
                extension = CertificateExtension(oidStr, isCritical, value)
                self.addExtension(extension)

    def wireDecode(self, buf, wireFormat = None):
        """
        Make sure the fields are populated after decoding
        """
        Data.wireDecode(self, buf, wireFormat)
        self.decode()

    def getNotBefore(self):
        """
        Returns the earliest date the certificate is valid at.
        :return: Timestamp as milliseconds since 1970.
        :rtype: float
        """
        return self._notBefore

    def getNotAfter(self):
        """
        Returns the latest date the certificate is valid at.
        :return: Timestamp as milliseconds since 1970.
        :rtype: float
        """
        return self._notAfter

    def getPublicKeyInfo(self):
        """
        :return: The PublicKey object stored in the certificate.
        :rtype: PublicKey
        """
        return self._publicKey

    def getPublicKeyDer(self):
        """
        Get the public key DER encoding.
        :return: The DER encoding Blob.
        :rtype: Blob
        :throws: RuntimeError if the public key is not set.
        """
        if self._publicKey.getKeyDer().isNull():
            raise RuntimeError("The public key is not set")

        return self._publicKey.getKeyDer()

    def setNotBefore(self, notBefore):
        self._notBefore = notBefore

    def setNotAfter(self, notAfter):
        self._notAfter = notAfter

    def setPublicKeyInfo(self, publicKey):
        """
        Assign a new public key to the certificate.
        :param publicKey: The new public key
        :type publicKey: PublicKey
        """
        self._publicKey = publicKey

    def getSubjectDescriptions(self):
        """
        :return: The subject description fields of the certificate.
        :rtype: list of CertificateSubjectDescription
        """
        return self._subjectDescriptionList

    def getExtensionList(self):
        """
        :return: The extension fields of the certificate.
        :rtype: list of CertificateExtension
        """
        return self._extensionList

    def getExtensions(self):
        """
        :deprecated: Use getExtensionList.
        """
        return self.getExtensionList()
Exemplo n.º 4
0
class Certificate(Data):
    epochStart = datetime(1970,1,1)
    def __init__(self, other=None):
        """
        Create a new certificate, optionally copying the
        contents of another Data object.
        :param other: (optional) A Data packet to copy the content from
        :type other: Data
        """
        super(Certificate,self).__init__(other)
        self._subjectDescriptionList = []
        self._extensionList = []
        if isinstance(other, Data):
            self.decode()
        else:
            self._notBefore = 1e37
            self._notAfter = -1e37
            self._publicKey = PublicKey()

    def isTooEarly(self):
        """
        Check if the certificate start date is in the future
        :return: True if the certificate cannot be used yet
        :rtype: boolean
        """

        secondsSince1970 = (datetime.now() - self.epochStart).total_seconds
        if secondsSince1970 < self.getNotBefore()/1000:
            return True
        return False

    def isTooLate(self):
        """
        Check if the certificate end date is in the past
        :return: True if the certificate has expired
        :rtype: boolean
        """
        secondsSince1970 = (datetime.now() - self.epochStart).total_seconds
        if secondsSince1970 > self.getNotAfter()/1000:
            return True
        return False

    def isInValidityPeriod(self, time):
        return self.getSignature().getValidityPeriod().isValid(time)

    def __str__(self):
        s = "Certificate name:\n"
        s += "  "+self.getName().toUri()+"\n"
        s += "Validity:\n"

        dateFormat = "%Y%m%dT%H%M%S"
        notBeforeStr = Common.datetimeFromTimestamp(self.getNotBefore()).strftime(dateFormat)
        notAfterStr = Common.datetimeFromTimestamp(self.getNotAfter()).strftime(dateFormat)

        s += "  NotBefore: " + notBeforeStr+"\n"
        s += "  NotAfter: " + notAfterStr + "\n"
        for sd in self._subjectDescriptionList:
            s += "Subject Description:\n"
            s += "  " + str(sd.getOid()) + ": " + sd.getValue().toRawStr() + "\n"

        s += "Public key bits:\n"
        s += Common.base64Encode(self.getPublicKeyDer().toBytes(), True)

        if len(self._extensionList) > 0:
            s += "Extensions:\n"
            for ext in self._extensionList:
                s += "  OID: "+ext.getOid()+"\n"
                s += "  Is critical: " + ('Y' if ext.isCritical() else 'N') + "\n"

                s += "  Value: " + str(ext.getValue()).encode('hex') + "\n"

        return s

    def addSubjectDescription(self, descr):
        """
        Add a subject description field to the certificate.
        :param descr: The CertificateSubjectDescription object to add
        """
        self._subjectDescriptionList.append(descr)

    def addExtension(self, ext):
        """
        Add an extension field to the certificate.
        :param ext: Th CertificateExtension object to add
        """
        self._extensionList.append(ext)

    def toDer(self):
        """
        Encode the certificate fields in DER format.
        :return: The DER encoded contents of the certificate.
        :rtype: DerNode
        """
        root = DerSequence()
        validity = DerSequence()
        notBefore = DerGeneralizedTime(self.getNotBefore())
        notAfter = DerGeneralizedTime(self.getNotAfter())

        validity.addChild(notBefore)
        validity.addChild(notAfter)

        root.addChild(validity)

        subjectList = DerSequence()
        for sd in self._subjectDescriptionList:
            child = sd.toDer()
            subjectList.addChild(child)

        root.addChild(subjectList)
        root.addChild(self._publicKey.toDer())

        if (len(self._extensionList) > 0):
            extnList = DerSequence()
            for ext in self._extensionList:
                child = ext.toDer()
                extnList.addChild(child)
            root.addChild(extnList)

        return root

    def encode(self):
        """
            Encode the contents of the certificate in DER format and set the
            Content and MetaInfo fields.
        """
        root = self.toDer()
        outVal = root.encode()
        self.setContent(Blob(outVal))
        self.getMetaInfo().setType(ContentType.KEY)

    def decode(self):
        """
        Populates the fields by decoding DER data from the Content.
        """
        root = DerNode.parse(self.getContent())

        # we need to ensure that there are:
        #   validity (notBefore, notAfter)
        #   subject list
        #   public key
        #   (optional) extension list

        rootChildren = root.getChildren()
        # 1st: validity info
        validityChildren = DerNode.getSequence(rootChildren, 0).getChildren()
        self._notBefore = validityChildren[0].toVal()
        self._notAfter = validityChildren[1].toVal()

        # 2nd: subjectList
        subjectChildren = DerNode.getSequence(rootChildren, 1).getChildren()
        for sd in subjectChildren:
            descriptionChildren = sd.getChildren()
            oidStr = descriptionChildren[0].toVal()
            value = descriptionChildren[1].toVal()

            subjectDesc = CertificateSubjectDescription(oidStr, value)
            self.addSubjectDescription(subjectDesc)

        # 3rd: public key
        publicKeyInfo = rootChildren[2].encode()
        self._publicKey = PublicKey(publicKeyInfo)

        if len(rootChildren) > 3:
            extensionChildren = DerNode.getSequence(rootChildren, 3).getChildren()
            for extInfo in extensionChildren:
                children = extInfo.getChildren()
                oidStr = children[0].toVal()
                isCritical = children[1].toVal()
                value = children[2].toVal()
                extension = CertificateExtension(oidStr, isCritical, value)
                self.addExtension(extension)

    def wireDecode(self, buf, wireFormat = None):
        """
        Make sure the fields are populated after decoding
        """
        Data.wireDecode(self, buf, wireFormat)
        self.decode()

    def getNotBefore(self):
        """
        Returns the earliest date the certificate is valid at.
        :return: Timestamp as milliseconds since 1970.
        :rtype: float
        """
        return self._notBefore

    def getNotAfter(self):
        """
        Returns the latest date the certificate is valid at.
        :return: Timestamp as milliseconds since 1970.
        :rtype: float
        """
        return self._notAfter

    def getPublicKeyInfo(self):
        """
        :return: The PublicKey object stored in the certificate.
        :rtype: PublicKey
        """
        return self._publicKey

    def getPublicKeyDer(self):
        """
        Get the public key DER encoding.
        :return: The DER encoding Blob.
        :rtype: Blob
        :throws: RuntimeError if the public key is not set.
        """
        if self._publicKey.getKeyDer().isNull():
            raise RuntimeError("The public key is not set")

        return self._publicKey.getKeyDer()

    def setNotBefore(self, notBefore):
        self._notBefore = notBefore

    def setNotAfter(self, notAfter):
        self._notAfter = notAfter

    def setPublicKeyInfo(self, publicKey):
        """
        Assign a new public key to the certificate.
        :param publicKey: The new public key
        :type publicKey: PublicKey
        """
        self._publicKey = publicKey

    def getSubjectDescriptions(self):
        """
        :return: The subject description fields of the certificate.
        :rtype: list of CertificateSubjectDescription
        """
        return self._subjectDescriptionList

    def getExtensionList(self):
        """
        :return: The extension fields of the certificate.
        :rtype: list of CertificateExtension
        """
        return self._extensionList

    def getExtensions(self):
        """
        :deprecated: Use getExtensionList.
        """
        return self.getExtensionList()