Пример #1
0
def test_pem_remove_rfc7468_delimiters():
    cert_str1 = fixture_cert_str(1)
    pem = XY509cert.pem_remove_rfc7468_delimiters(cert_str1,
                                                  optional_delimiter=True)
    assert pem == fixture_cert_str(2)
    with pytest.raises(ValidationError):
        pem = XY509cert.pem_remove_rfc7468_delimiters(fixture_cert_str(2),
                                                      optional_delimiter=False)
Пример #2
0
 def _validate_authz(self) -> None:
     try:
         xml_sig_verifyer_response = self.ed.validateSignature()
         self.signer_cert_pem = xml_sig_verifyer_response.signer_cert_pem
         self.signer_cert_cn = XY509cert(
             self.signer_cert_pem).getSubjectCN()
         if len(self.ed.get_entityid_hostname()) == 0:
             self.authz_ok = False
             self.val_mesg_dict[
                 'Hostname'] = 'Cannot authorize: no hostname found when URL-parsing entityID'
             raise NoFurtherValidation
         try:
             org_ids = self.policydict.get_orgids_for_signer(
                 xml_sig_verifyer_response.signer_cert_pem)
             allowedDomains = self.policydict.getAllowedNamespacesForOrgs(
                 org_ids)
             self.ed.validateDomainNames(allowedDomains)
             self.orgid = self.policydict.get_orgid(
                 self.ed.get_entityid_hostname())
             self.orgcn = self.policydict.get_orgcn(self.orgid)
             self.authz_ok = True
         except (PVZDuserexception) as e:
             self.authz_ok = False
             self.val_mesg_dict['Hostname'] = self._format_val_msg(e)
     except (PVZDuserexception) as e:
         self.authz_ok = False
         self.val_mesg_dict['Validate signature'] = self._format_val_msg(e)
Пример #3
0
 def _save_trustedcerts_report(self) -> None:
     '''  Print human readable copy of trusted certificates, non-authoritative  '''
     pass
     for cert_pem in self.trusted_certs:
         cert = XY509cert(cert_pem, inform='PEM')  # TODO: check encoding
         cert_report = (f"Subject: {cert.getSubject_str()}; "
                        f"issuer: {cert.getIssuer_str()}; "
                        f"not valid after: {cert.notAfter_str()}\n")
     self.aodsfh.save_trustedcerts_report(cert_report)
Пример #4
0
    def checkCerts(self) -> None:
        """ validate that included signing and encryption certificates meet following conditions:
            * not expired AND
            * issued by a CA listed as issuer in the related trust store) AND
            * the x509subject's CN matches the hostname of the entityDescriptor
        """
        for cert_pem in self._getCerts(
                'IDP'):  # certs in IDPSSODescriptor elements
            if cert_pem is None:
                continue
            cert = XY509cert(cert_pem)
            if not cert.isNotExpired():
                raise CertExpiredError('Certificate is expired')
            x509storeContext = crypto.X509StoreContext(
                self.IDP_trustStore.x509store, cert.cert)
            try:
                x509storeContext.verify_certificate()
            except crypto.X509StoreContextError as e:
                raise CertInvalidError(('Certificate validation failed. ' +
                                        str(e) + ' ' + cert.getIssuer_str()))
            if cert.getSubject_str().find('/CN=' +
                                          self.get_entityid_hostname()) < 0:
                raise EdHostnameNotMatchingCertSubject(
                    'Hostname of entityID (%s) not matching CN in cert subject (%s)'
                    % (self.get_entityid_hostname(), cert.getSubject_str()))

        for cert_pem in self._getCerts(
                'SP'):  # certs in SPSSODescriptor elements
            if cert_pem is None:
                continue
            cert = XY509cert(cert_pem)
            if not cert.isNotExpired():
                raise CertExpiredError(
                    f"Certificate is expired since {cert.notValidAfter()}; subject: {cert.getSubject_str}"
                )
            x509storeContext = crypto.X509StoreContext(
                self.SP_trustStore.x509store, cert.cert)
            try:
                x509storeContext.verify_certificate()
            except crypto.X509StoreContextError as e:
                raise CertInvalidError(('Certificate validation failed. ' +
                                        str(e) + ' ' + cert.getIssuer_str()))
        logging.debug('Entity certificates valid for ' +
                      self.ed.get_entityid())
Пример #5
0
 def _load_certlist_from_certdir(self):
     if not self.pvzdconf.trustedcertsdir.is_dir():
         raise ValidationError(f"Trusted Certs directory not found: {str(self.pvzdconf.trustedcertsdir)}")
     self.certs = set()
     for certfile in self.pvzdconf.trustedcertsdir.iterdir():
         if certfile.suffix == '.pem':
             pem = XY509cert.pem_remove_rfc7468_delimiters(
                 certfile.read_text(),
                 optional_delimiter=True)
             pem_single_line = pem.replace('\n', '').strip()
             self.certs.add(pem_single_line)
         else:
             logging.debug(f"skipping file in certdir because extension != '.pem': {certfile}")
Пример #6
0
 def cert2ed(cert_str, entityid, samlrole):
     cert_str_nodelimiters = XY509cert.pem_remove_rfc7468_delimiters(
         cert_str, optional_delimiter=True)
     if samlrole == 'IDP':
         entityDescriptor = """\
 <md:EntityDescriptor entityID="{eid}" xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
     xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
     xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
     xmlns:pvzd="http://egov.gv.at/pvzd1.xsd"
     pvzd:pvptype="R-Profile">
   <md:IDPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
     <md:KeyDescriptor use="signing">
       <ds:KeyInfo>
         <ds:X509Data>
            <ds:X509Certificate>
 {pem}
            </ds:X509Certificate>
         </ds:X509Data>
       </ds:KeyInfo>
     </md:KeyDescriptor>
     <md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="{eid}/idp/unused"/>
   </md:IDPSSODescriptor>
 </md:EntityDescriptor>""".format(eid=entityid, pem=cert_str_nodelimiters)
     elif samlrole == 'SP':
         entityDescriptor = """\
 <md:EntityDescriptor entityID="{eid}" xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
     xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
     xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
     xmlns:pvzd="http://egov.gv.at/pvzd1.xsd"
     pvzd:pvptype="R-Profile">
   <md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
     <md:KeyDescriptor use="signing">
       <ds:KeyInfo>
         <ds:X509Data>
            <ds:X509Certificate>
 {pem}
            </ds:X509Certificate>
         </ds:X509Data>
       </ds:KeyInfo>
     </md:KeyDescriptor>
     <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                                  Location="{eid}/acs/unused" index="0" isDefault="true"/>
   </md:SPSSODescriptor>
 </md:EntityDescriptor>""".format(eid=entityid, pem=cert_str_nodelimiters)
     else:
         raise EntityRoleNotSupportedError(
             f"Only IDP and SP entity roles implemented, but %s given {samlrole}"
         )
     return entityDescriptor
Пример #7
0
 def get_signing_certs(self, samlrole: str = 'IDP') -> [XY509cert]:
     x509certs = []
     # if samlrole not in ('any', 'IDP', 'SP'):
     #     raise InputValueError("samlrole must be on of 'any', 'IDP', 'SP'")
     if samlrole not in ('IDP', ):
         raise InputValueError("samlrole must be 'IDP'")
     idpssodesc = self.tree.xpath('//md:IDPSSODescriptor',
                                  namespaces={'md': XMLNS_MD})
     if len(idpssodesc) > 0:
         keydescriptors = idpssodesc[0].findall(XMLNS_MD_PREFIX +
                                                'KeyDescriptor')
         for kd in keydescriptors:
             if 'use' in kd.attrib and kd.attrib['use'] == 'encryption':
                 pass
             else:  # signing certs are those with use="signing" or have no use attribute
                 for x509cert in kd.iter(XMLNS_DSIG_PREFIX +
                                         'X509Certificate'):
                     x509certs.append(XY509cert(x509cert.text.strip()))
     return x509certs
Пример #8
0
 def save(self, *args, **kwargs):
     self.not_after = XY509cert(self.cert).notAfter_str()
     self.org_cn = self.gvouid_parent.gvouid.cn
     self.subject_cn = XY509cert(self.cert).getSubjectCN()
     super().save(*args, **kwargs)
Пример #9
0
 def save(self, *args, **kwargs):
     xy509cert = XY509cert(self.cacert)
     self.subject_cn = xy509cert.getSubjectCN()
     super().save()
Пример #10
0
 def save(self, *args, **kwargs):
     self.issuer_cn = XY509cert(self.cert).getIssuer_str()
     self.not_after = XY509cert(self.cert).notAfter_str()
     self.pubkey = XY509cert(self.cert).get_pubkey()
     self.subject_cn = XY509cert(self.cert).getSubject_str()
     super().save(*args, **kwargs)