Example #1
0
 def sign(self):
     logger.debug('certificate.sign')
     assert self.cert != None
     assert self.issuerSubject != None
     assert self.issuerKey != None
     self.cert.set_issuer(self.issuerSubject)
     self.cert.sign(self.issuerKey.get_openssl_pkey(), self.digest)
Example #2
0
 def sign(self):
     logger.debug('certificate.sign')
     assert self.cert != None
     assert self.issuerSubject != None
     assert self.issuerKey != None
     self.cert.set_issuer(self.issuerSubject)
     self.cert.sign(self.issuerKey.get_openssl_pkey(), self.digest)
Example #3
0
 def get_extensions(self):
     # pyOpenSSL does not have a way to get extensions
     triples=[]
     m2x509 = X509.load_cert_string(self.save_to_string())
     nb_extensions=m2x509.get_ext_count()
     logger.debug("X509 had %d extensions"%nb_extensions)
     for i in range(nb_extensions):
         ext=m2x509.get_ext_at(i)
         triples.append( (ext.get_name(), ext.get_value(), ext.get_critical(),) )
     return triples
Example #4
0
 def __init__(self, create=False, subject=None, string=None, filename=None, uuid=None, hrn=None, urn=None, lifeDays=1825):
     
     Certificate.__init__(self, lifeDays, create, subject, string, filename)
     if subject:
         logger.debug("Creating GID for subject: %s" % subject)
     if uuid:
         self.uuid = int(uuid)
     if hrn:
         self.hrn = hrn
         self.urn = hrn_to_urn(hrn, 'unknown')
     if urn:
         self.urn = urn
         self.hrn, type = urn_to_hrn(urn)
Example #5
0
 def get_extensions(self):
     # pyOpenSSL does not have a way to get extensions
     triples = []
     m2x509 = X509.load_cert_string(self.save_to_string())
     nb_extensions = m2x509.get_ext_count()
     logger.debug("X509 had %d extensions" % nb_extensions)
     for i in range(nb_extensions):
         ext = m2x509.get_ext_at(i)
         triples.append((
             ext.get_name(),
             ext.get_value(),
             ext.get_critical(),
         ))
     return triples
Example #6
0
    def __init__(self,
                 create=False,
                 subject=None,
                 string=None,
                 filename=None,
                 uuid=None,
                 hrn=None,
                 urn=None,
                 lifeDays=1825):

        Certificate.__init__(self, lifeDays, create, subject, string, filename)
        if subject:
            logger.debug("Creating GID for subject: %s" % subject)
        if uuid:
            self.uuid = int(uuid)
        if hrn:
            self.hrn = hrn
            self.urn = hrn_to_urn(hrn, 'unknown')
        if urn:
            self.urn = urn
            self.hrn, type = urn_to_hrn(urn)
Example #7
0
    def verify_issuer(self, trusted_gids):
        root_cred = self.get_credential_list()[-1]
        root_target_gid = root_cred.get_gid_object()
        root_cred_signer = root_cred.get_signature().get_issuer_gid()

        # Case 1:
        # Allow non authority to sign target and cred about target.
        #
        # Why do we need to allow non authorities to sign?
        # If in the target gid validation step we correctly
        # checked that the target is only signed by an authority,
        # then this is just a special case of case 3.
        # This short-circuit is the common case currently -
        # and cause GID validation doesn't check 'authority',
        # this allows users to generate valid slice credentials.
        if root_target_gid.is_signed_by_cert(root_cred_signer):
            # cred signer matches target signer, return success
            return

        # Case 2:
        # Allow someone to sign credential about themeselves. Used?
        # If not, remove this.
        #root_target_gid_str = root_target_gid.save_to_string()
        #root_cred_signer_str = root_cred_signer.save_to_string()
        #if root_target_gid_str == root_cred_signer_str:
        #    # cred signer is target, return success
        #    return

        # Case 3:

        # root_cred_signer is not the target_gid
        # So this is a different gid that we have not verified.
        # xmlsec1 verified the cert chain on this already, but
        # it hasn't verified that the gid meets the HRN namespace
        # requirements.
        # Below we'll ensure that it is an authority.
        # But we haven't verified that it is _signed by_ an authority
        # We also don't know if xmlsec1 requires that cert signers
        # are marked as CAs.

        # Note that if verify() gave us no trusted_gids then this
        # call will fail. So skip it if we have no trusted_gids
        if trusted_gids and len(trusted_gids) > 0:
            root_cred_signer.verify_chain(trusted_gids)
        else:
            logger.debug(
                "No trusted gids. Cannot verify that cred signer is signed by a trusted authority. Skipping that check."
            )

        # See if the signer is an authority over the domain of the target.
        # There are multiple types of authority - accept them all here
        # Maybe should be (hrn, type) = urn_to_hrn(root_cred_signer.get_urn())
        root_cred_signer_type = root_cred_signer.get_type()
        if (root_cred_signer_type.find('authority') == 0):
            #logger.debug('Cred signer is an authority')
            # signer is an authority, see if target is in authority's domain
            signerhrn = root_cred_signer.get_hrn()
            if hrn_authfor_hrn(signerhrn, root_target_gid.get_hrn()):
                return

        # We've required that the credential be signed by an authority
        # for that domain. Reasonable and probably correct.
        # A looser model would also allow the signer to be an authority
        # in my control framework - eg My CA or CH. Even if it is not
        # the CH that issued these, eg, user credentials.

        # Give up, credential does not pass issuer verification

        raise CredentialNotVerifiable(
            "Could not verify credential owned by %s for object %s. Cred signer %s not the trusted authority for Cred target %s"
            % (self.gidCaller.get_urn(), self.gidObject.get_urn(),
               root_cred_signer.get_hrn(), root_target_gid.get_hrn()))
Example #8
0
    def verify_chain(self, trusted_certs=None):
        # Verify a chain of certificates. Each certificate must be signed by
        # the public key contained in it's parent. The chain is recursed
        # until a certificate is found that is signed by a trusted root.

        # verify expiration time
        if self.cert.has_expired():
            logger.debug("verify_chain: NO, Certificate %s has expired" %
                         self.get_printable_subject())
            raise CertExpired(self.get_printable_subject(), "client cert")

        # if this cert is signed by a trusted_cert, then we are set
        for trusted_cert in trusted_certs:
            if self.is_signed_by_cert(trusted_cert):
                # verify expiration of trusted_cert ?
                if not trusted_cert.cert.has_expired():
                    logger.debug(
                        "verify_chain: YES. Cert %s signed by trusted cert %s"
                        % (self.get_printable_subject(),
                           trusted_cert.get_printable_subject()))
                    return trusted_cert
                else:
                    logger.debug(
                        "verify_chain: NO. Cert %s is signed by trusted_cert %s, but that signer is expired..."
                        % (self.get_printable_subject(),
                           trusted_cert.get_printable_subject()))
                    raise CertExpired(
                        self.get_printable_subject(),
                        " signer trusted_cert %s" %
                        trusted_cert.get_printable_subject())

        # if there is no parent, then no way to verify the chain
        if not self.parent:
            logger.debug(
                "verify_chain: NO. %s has no parent and issuer %s is not in %d trusted roots"
                % (self.get_printable_subject(), self.get_issuer(),
                   len(trusted_certs)))
            raise CertMissingParent(
                self.get_printable_subject() +
                ": Issuer %s is not one of the %d trusted roots, and cert has no parent."
                % (self.get_issuer(), len(trusted_certs)))

        # if it wasn't signed by the parent...
        if not self.is_signed_by_cert(self.parent):
            logger.debug("verify_chain: NO. %s is not signed by parent %s, but by %s"%\
                             (self.get_printable_subject(),
                              self.parent.get_printable_subject(),
                              self.get_issuer()))
            raise CertNotSignedByParent("%s: Parent %s, issuer %s"\
                                            % (self.get_printable_subject(),
                                               self.parent.get_printable_subject(),
                                               self.get_issuer()))

        # Confirm that the parent is a CA. Only CAs can be trusted as
        # signers.
        # Note that trusted roots are not parents, so don't need to be
        # CAs.
        # Ugly - cert objects aren't parsed so we need to read the
        # extension and hope there are no other basicConstraints
        if not self.parent.isCA and not (
                self.parent.get_extension('basicConstraints') == 'CA:TRUE'):
            logger.warn("verify_chain: cert %s's parent %s is not a CA" % \
                            (self.get_printable_subject(), self.parent.get_printable_subject()))
            raise CertNotSignedByParent("%s: Parent %s not a CA" %
                                        (self.get_printable_subject(),
                                         self.parent.get_printable_subject()))

        # if the parent isn't verified...
        logger.debug("verify_chain: .. %s, -> verifying parent %s"%\
                         (self.get_printable_subject(),self.parent.get_printable_subject()))
        self.parent.verify_chain(trusted_certs)

        return
Example #9
0
    def verify_chain(self, trusted_certs = None):
        # Verify a chain of certificates. Each certificate must be signed by
        # the public key contained in it's parent. The chain is recursed
        # until a certificate is found that is signed by a trusted root.

        # verify expiration time
        if self.cert.has_expired():
            logger.debug("verify_chain: NO, Certificate %s has expired" % self.get_printable_subject())
            raise CertExpired(self.get_printable_subject(), "client cert")

        # if this cert is signed by a trusted_cert, then we are set
        for trusted_cert in trusted_certs:
            if self.is_signed_by_cert(trusted_cert):
                # verify expiration of trusted_cert ?
                if not trusted_cert.cert.has_expired():
                    logger.debug("verify_chain: YES. Cert %s signed by trusted cert %s"%(
                            self.get_printable_subject(), trusted_cert.get_printable_subject()))
                    return trusted_cert
                else:
                    logger.debug("verify_chain: NO. Cert %s is signed by trusted_cert %s, but that signer is expired..."%(
                            self.get_printable_subject(),trusted_cert.get_printable_subject()))
                    raise CertExpired(self.get_printable_subject()," signer trusted_cert %s"%trusted_cert.get_printable_subject())

        # if there is no parent, then no way to verify the chain
        if not self.parent:
            logger.debug("verify_chain: NO. %s has no parent and issuer %s is not in %d trusted roots"%(self.get_printable_subject(), self.get_issuer(), len(trusted_certs)))
            raise CertMissingParent(self.get_printable_subject() + ": Issuer %s is not one of the %d trusted roots, and cert has no parent." % (self.get_issuer(), len(trusted_certs)))

        # if it wasn't signed by the parent...
        if not self.is_signed_by_cert(self.parent):
            logger.debug("verify_chain: NO. %s is not signed by parent %s, but by %s"%\
                             (self.get_printable_subject(), 
                              self.parent.get_printable_subject(), 
                              self.get_issuer()))
            raise CertNotSignedByParent("%s: Parent %s, issuer %s"\
                                            % (self.get_printable_subject(), 
                                               self.parent.get_printable_subject(),
                                               self.get_issuer()))

        # Confirm that the parent is a CA. Only CAs can be trusted as
        # signers.
        # Note that trusted roots are not parents, so don't need to be
        # CAs.
        # Ugly - cert objects aren't parsed so we need to read the
        # extension and hope there are no other basicConstraints
        if not self.parent.isCA and not (self.parent.get_extension('basicConstraints') == 'CA:TRUE'):
            logger.warn("verify_chain: cert %s's parent %s is not a CA" % \
                            (self.get_printable_subject(), self.parent.get_printable_subject()))
            raise CertNotSignedByParent("%s: Parent %s not a CA" % (self.get_printable_subject(),
                                                                    self.parent.get_printable_subject()))

        # if the parent isn't verified...
        logger.debug("verify_chain: .. %s, -> verifying parent %s"%\
                         (self.get_printable_subject(),self.parent.get_printable_subject()))
        self.parent.verify_chain(trusted_certs)

        return
Example #10
0
    def verify_issuer(self, trusted_gids):
        root_cred = self.get_credential_list()[-1]
        root_target_gid = root_cred.get_gid_object()
        root_cred_signer = root_cred.get_signature().get_issuer_gid()

        # Case 1:
        # Allow non authority to sign target and cred about target.
        #
        # Why do we need to allow non authorities to sign?
        # If in the target gid validation step we correctly
        # checked that the target is only signed by an authority,
        # then this is just a special case of case 3.
        # This short-circuit is the common case currently -
        # and cause GID validation doesn't check 'authority',
        # this allows users to generate valid slice credentials.
        if root_target_gid.is_signed_by_cert(root_cred_signer):
            # cred signer matches target signer, return success
            return

        # Case 2:
        # Allow someone to sign credential about themeselves. Used?
        # If not, remove this.
        #root_target_gid_str = root_target_gid.save_to_string()
        #root_cred_signer_str = root_cred_signer.save_to_string()
        #if root_target_gid_str == root_cred_signer_str:
        #    # cred signer is target, return success
        #    return

        # Case 3:

        # root_cred_signer is not the target_gid
        # So this is a different gid that we have not verified.
        # xmlsec1 verified the cert chain on this already, but
        # it hasn't verified that the gid meets the HRN namespace
        # requirements.
        # Below we'll ensure that it is an authority.
        # But we haven't verified that it is _signed by_ an authority
        # We also don't know if xmlsec1 requires that cert signers
        # are marked as CAs.

        # Note that if verify() gave us no trusted_gids then this
        # call will fail. So skip it if we have no trusted_gids
        if trusted_gids and len(trusted_gids) > 0:
            root_cred_signer.verify_chain(trusted_gids)
        else:
            logger.debug("No trusted gids. Cannot verify that cred signer is signed by a trusted authority. Skipping that check.")

        # See if the signer is an authority over the domain of the target.
        # There are multiple types of authority - accept them all here
        # Maybe should be (hrn, type) = urn_to_hrn(root_cred_signer.get_urn())
        root_cred_signer_type = root_cred_signer.get_type()
        if (root_cred_signer_type.find('authority') == 0):
            #logger.debug('Cred signer is an authority')
            # signer is an authority, see if target is in authority's domain
            signerhrn = root_cred_signer.get_hrn()
            if hrn_authfor_hrn(signerhrn, root_target_gid.get_hrn()):
                return

        # We've required that the credential be signed by an authority
        # for that domain. Reasonable and probably correct.
        # A looser model would also allow the signer to be an authority
        # in my control framework - eg My CA or CH. Even if it is not
        # the CH that issued these, eg, user credentials.

        # Give up, credential does not pass issuer verification

        raise CredentialNotVerifiable("Could not verify credential owned by %s for object %s. Cred signer %s not the trusted authority for Cred target %s" % (self.gidCaller.get_urn(), self.gidObject.get_urn(), root_cred_signer.get_hrn(), root_target_gid.get_hrn()))