Esempio n. 1
0
    def sign(self):
        # TODO: change hardcodeed key paths to environement variables
        cert = open('cert.pem').read()
        key = open('key.pem').read()

        root = etree.fromstring(self._xml.encode('ISO-8859-1'),
                                parser=etree.XMLParser(encoding='ISO-8859-1'))
        signed_root = xmldsig(root, digest_algorithm='sha1').sign(
            algorithm='rsa-sha1', key=key, cert=cert)
        signed_root.xpath(
            '//ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/ds:Signature',
            namespaces={
                'ext':
                'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2',
                'ds': 'http://www.w3.org/2000/09/xmldsig#'
            })[0].attrib['Id'] = 'SignSUNAT'
        self._xml = etree.tostring(signed_root, encoding='ISO-8859-1')

        print(
            xmldsig(signed_root).verify(require_x509=True,
                                        x509_cert=cert,
                                        ca_pem_file=key,
                                        ca_path=None,
                                        hmac_key=None,
                                        validate_schema=True,
                                        parser=None,
                                        id_attribute=None))
Esempio n. 2
0
    def verify(self, xml_file_name) -> str:
        """ verify xmldsig and return signerCertificate
        option: validate against a specific signing certificate.
        """
        with open(xml_file_name) as fd:
            xml_str = fd.read()
        xml_bytes = xml_str.encode(localconfig.XML_ENCODING)
        try:
            if self.sig_cert is None:  # TODO - does not work yet https://github.com/kislyuk/signxml/issues/41
                verified_et_element = signxml.xmldsig(xml_bytes).verify(
                        #ca_pem_file=localconfig.UNITTEST_CACERT,
                        ca_path=localconfig.UNITTEST_CADIR)
            else:
                with open(self.sig_cert) as fd:
                    cert = fd.read()
                verified_et_element = signxml.xmldsig(xml_bytes).verify(x509_cert=cert)
        except signxml.InvalidDigest:
            logging.info('Invalid digest in ' + xml_file_name)
            raise
        except signxml.InvalidInput:
            logging.info('Invalid input in ' + xml_file_name)
            raise

        signed_data_bytes = ElementTree.tostring(verified_et_element,
                                                 xml_declaration=True,
                                                 encoding=localconfig.XML_ENCODING)
        signed_data_str = signed_data_bytes.decode(localconfig.XML_ENCODING)
        cert_b64 = XY509cert.pem_remove_rfc7468_delimiters(cert,
                                                           optional_delimiter=True,
                                                           remove_whitespace=True)
        r = XmlSigVerifyerResponse(signed_data_str, cert_b64)
        return r
Esempio n. 3
0
def parse_saml(saml, ip, disable_checks=[], decode=True):
    logger = logging.getLogger('islykill')
    logger.debug('Starting SAML authentication process')
    logger.debug(saml)
    try:
        logger.debug(saml.__class__)
        if decode:
            dec_resp = decode_response(saml)
        else:
            dec_resp = saml

        logger.debug(dec_resp.__class__)

        ca_pem_loc = os.path.dirname(os.path.abspath(__file__))
        ca_pem_file = os.path.join(ca_pem_loc, 'Oll_kedjan.pem')

        logger.debug('Using ca_pem_file: %s' % ca_pem_file)

        xmldsig(dec_resp).verify(ca_pem_file=ca_pem_file)

        logger.debug('verify OK')

        xml = get_xmldoc(dec_resp)
        assertion = get_assertion(xml)
        attributes = get_assertion_attributes(assertion)
        conditions = get_conditions(assertion)

        logger.debug('all XML fetched...')

        now = datetime.datetime.now()

        if not verify_ip(attributes['IPAddress'], ip):
            checkError('verify_ip failed', disable_checks)
        if not verify_date_is_after(
                strptime(conditions.attrib['NotBefore']), now):
            checkError('verify_date_is_after failed', disable_checks)
        if not verify_date_is_before(
                strptime(conditions.attrib['NotOnOrAfter']), now):
            checkError('verify_date_is_before', disable_checks)
            logger.warning(
                'NotOnOrAfter: %s',
                conditions.attrib['NotOnOrAfter'])
            logger.warning(
                'Parsed date: %s',
                strptime(conditions.attrib['NotOnOrAfter']))
            logger.warning(
                'Current date: %s',
                now)
        kt = attributes['UserSSN']
        logger.debug('authenticated successfully: %s', kt)
        return SAMLResponse(kt)
    except AuthenticationError as e:
        logger.error('AuthenticationError: %s', e.message)
        raise e
    except Exception:
        logger.error('Unknown error occurred:')
        logger.error(traceback.format_exc())
        from django.core.mail import mail_admins
        mail_admins('SAML authentication error', traceback.format_exc())
        checkError('Unknown error', disable_checks)
Esempio n. 4
0
    def verify(self, xml_file_name) -> str:
        """ verify xmldsig and return signerCertificate
        option: validate against a specific signing certificate.
        """
        with open(xml_file_name) as fd:
            xml_str = fd.read()
        xml_bytes = xml_str.encode(localconfig.XML_ENCODING)
        try:
            if self.sig_cert is None:  # TODO - does not work yet https://github.com/kislyuk/signxml/issues/41
                verified_et_element = signxml.xmldsig(xml_bytes).verify(
                    #ca_pem_file=localconfig.UNITTEST_CACERT,
                    ca_path=localconfig.UNITTEST_CADIR)
            else:
                with open(self.sig_cert) as fd:
                    cert = fd.read()
                verified_et_element = signxml.xmldsig(xml_bytes).verify(
                    x509_cert=cert)
        except signxml.InvalidDigest:
            logging.info('Invalid digest in ' + xml_file_name)
            raise
        except signxml.InvalidInput:
            logging.info('Invalid input in ' + xml_file_name)
            raise

        signed_data_bytes = ElementTree.tostring(
            verified_et_element,
            xml_declaration=True,
            encoding=localconfig.XML_ENCODING)
        signed_data_str = signed_data_bytes.decode(localconfig.XML_ENCODING)
        cert_b64 = XY509cert.pem_remove_rfc7468_delimiters(
            cert, optional_delimiter=True, remove_whitespace=True)
        r = XmlSigVerifyerResponse(signed_data_str, cert_b64)
        return r
Esempio n. 5
0
def _entregaFirma(self, xml_factura):
    path = os.getcwd(
    ) + '/openerp/v7/addons_econube/account_invoice_cl/connect/firma/%s'
    p12 = path % 'contact people.pfx'  #'cert_econube_2016.p12'
    p12 = crypto.load_pkcs12(file(p12, 'rb').read(), 'chiledar')
    certificate = p12.get_certificate()
    private_key = p12.get_privatekey()
    type_ = FILETYPE_PEM
    signature = certificate.get_signature_algorithm()
    type_pk = private_key.type()
    str_private_key = crypto.dump_privatekey(type_, private_key)
    str_certificate_key = crypto.dump_certificate(type_, certificate)
    fields = certificate.get_subject().get_components()
    root = etree.fromstring(xml_factura.strip())
    xmldsig(root).sign(algorithm='rsa-sha1',
                       key=str_private_key,
                       cert=str_certificate_key,
                       c14n_algorithm='REC-xml-c14n-20010315')
    xml_firmado = etree.tostring(root, encoding="ISO-8859-1", method="xml")
    verified_data = xmldsig(xml_firmado).verify(x509_cert=str_certificate_key)
    xml_verificado = etree.tostring(verified_data,
                                    encoding="ISO-8859-1",
                                    method="xml")
    #    client = _connect_GetTokenFromSeed()
    #    res = client.service.getToken(xml_verificado)
    #    xml_verificado =  etree.tostring(verified_data, pretty_print = True, method="xml")
    #    res = etree.tostring(res, pretty_print = True, method="xml")
    return xml_verificado
Esempio n. 6
0
    def ParseSAMLResponse(strACSUrl, strEncodedSAMLResponse):

        cert = open("static/certificates/SignCertFromCentrify.cer").read()
        strDecodedSAMLResponse = b64decode(strEncodedSAMLResponse)
        authn_response = ""

        try:
            xmldsig(strDecodedSAMLResponse).verify(x509_cert=cert)

            root = etree.fromstring(b64decode(strEncodedSAMLResponse))

            strNameIdNode = root.xpath(
                '//saml2p:Response/xmlns:Assertion/xmlns:Subject/xmlns:NameID',
                namespaces={
                    'saml2p': 'urn:oasis:names:tc:SAML:2.0:protocol',
                    'xmlns': 'urn:oasis:names:tc:SAML:2.0:assertion'
                })

            strNameId = etree.tostring(strNameIdNode[0], method="text")

            authn_response = "SAML Response from IDP Was Accepted. Authenticated user is " + str(
                strNameId)[1:]

        except:
            authn_response = "SAML Response from IDP Was Not Accepted"

        return authn_response
Esempio n. 7
0
    def sign(self):
        # TODO: change hardcodeed key paths to environement variables
        cert = open('cert.pem').read()
        key = open('key.pem').read()

        root = etree.fromstring(self._xml.encode('ISO-8859-1'), parser=etree.XMLParser(encoding='ISO-8859-1'))
        signed_root = xmldsig(root, digest_algorithm='sha1').sign(algorithm='rsa-sha1', key=key, cert=cert)
        self._xml = etree.tostring(signed_root, encoding='ISO-8859-1')

        print (xmldsig(signed_root).verify(require_x509=True, x509_cert=cert,
                                           ca_pem_file=key, ca_path=None,
                                           hmac_key=None, validate_schema=True,
                                           parser=None, uri_resolver=None,
                                           id_attribute=None))
Esempio n. 8
0
    def sign(self):
        # TODO: change hardcodeed key paths to environement variables
        cert = open('cert.pem').read()
        key = open('key.pem').read()

        root = etree.fromstring(self._xml.encode('ISO-8859-1'), parser=etree.XMLParser(encoding='ISO-8859-1'))
        signed_root = xmldsig(root, digest_algorithm='sha1').sign(algorithm='rsa-sha1', key=key, cert=cert)
        signed_root.xpath('//ext:UBLExtensions/ext:UBLExtension/ext:ExtensionContent/ds:Signature',
                          namespaces={'ext': 'urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2',
                                      'ds': 'http://www.w3.org/2000/09/xmldsig#'})[0].attrib['Id'] = 'SignSUNAT'
        self._xml = etree.tostring(signed_root, encoding='ISO-8859-1')

        print (xmldsig(signed_root).verify(require_x509=True, x509_cert=cert,
                                           ca_pem_file=key, ca_path=None,
                                           hmac_key=None, validate_schema=True,
                                           parser=None, id_attribute=None))
Esempio n. 9
0
 def sign_seed(self, message, privkey, cert):
     doc = etree.fromstring(message)
     signed_node = xmldsig(doc, digest_algorithm=u'sha1').sign(
         method=methods.enveloped,
         algorithm=u'rsa-sha1',
         key=privkey.encode('ascii'),
         cert=cert)
     msg = etree.tostring(signed_node, pretty_print=True).replace('ds:', '')
     return msg
    def ParseSAMLResponse(strACSUrl, strEncodedSAMLResponse):

        cert = open("static/certificates/SignCertFromCentrify.cer").read()
        strDecodedSAMLResponse = b64decode(strEncodedSAMLResponse)
        authn_response = ""

        try:
            xmldsig(strDecodedSAMLResponse).verify(x509_cert=cert)
            
            root = etree.fromstring(b64decode(strEncodedSAMLResponse))
            
            strNameIdNode = root.xpath('//saml2p:Response/xmlns:Assertion/xmlns:Subject/xmlns:NameID', namespaces={'saml2p': 'urn:oasis:names:tc:SAML:2.0:protocol', 'xmlns': 'urn:oasis:names:tc:SAML:2.0:assertion'})

            strNameId = etree.tostring(strNameIdNode[0], method="text")

            authn_response = "SAML Response from IDP Was Accepted. Authenticated user is " + str(strNameId)[1:]

        except:
            authn_response = "SAML Response from IDP Was Not Accepted"

        return authn_response
Esempio n. 11
0
    def sign(self):
        # TODO: change hardcodeed key paths to environement variables
        cert = open('cert.pem').read()
        key = open('key.pem').read()

        root = etree.fromstring(self._xml.encode('ISO-8859-1'),
                                parser=etree.XMLParser(encoding='ISO-8859-1'))
        signed_root = xmldsig(root, digest_algorithm='sha1').sign(
            algorithm='rsa-sha1', key=key, cert=cert)
        self._xml = etree.tostring(signed_root, encoding='ISO-8859-1')

        print(
            xmldsig(signed_root).verify(require_x509=True,
                                        x509_cert=cert,
                                        ca_pem_file=key,
                                        ca_path=None,
                                        hmac_key=None,
                                        validate_schema=True,
                                        parser=None,
                                        uri_resolver=None,
                                        id_attribute=None))
Esempio n. 12
0
def _entregaFirma (self,xml_factura):
    path = os.getcwd() + '/openerp/v7/addons_econube/account_invoice_cl/connect/firma/%s'
    p12 = path % 'contact people.pfx' #'cert_econube_2016.p12'
    p12 = crypto.load_pkcs12(file(p12, 'rb').read(), 'chiledar')
    certificate = p12.get_certificate()
    private_key = p12.get_privatekey()
    type_ = FILETYPE_PEM
    signature = certificate.get_signature_algorithm()
    type_pk = private_key.type()
    str_private_key=crypto.dump_privatekey(type_, private_key)
    str_certificate_key=crypto.dump_certificate(type_, certificate)
    fields = certificate.get_subject().get_components()
    root = etree.fromstring(xml_factura.strip())
    xmldsig(root).sign(algorithm='rsa-sha1',key=str_private_key, cert=str_certificate_key,c14n_algorithm='REC-xml-c14n-20010315')
    xml_firmado =  etree.tostring(root,encoding="ISO-8859-1", method="xml")
    verified_data = xmldsig(xml_firmado).verify(x509_cert=str_certificate_key)
    xml_verificado =  etree.tostring(verified_data,encoding="ISO-8859-1", method="xml")
#    client = _connect_GetTokenFromSeed()                 
#    res = client.service.getToken(xml_verificado)
#    xml_verificado =  etree.tostring(verified_data, pretty_print = True, method="xml")
#    res = etree.tostring(res, pretty_print = True, method="xml")
    return xml_verificado
Esempio n. 13
0
def get_saml(request, token):
	try:
		# Fetch SAML 1.2 info
		AI = settings.SAML_1['AUTH']
		client = Client(AI['wsdl'], username=AI['login'], password=AI['password'])
		ipaddr = request.META.get('REMOTE_ADDR')
		result = client.service.generateSAMLFromToken(token, ipaddr)

		if result['status']['message'] != 'Success':
			raise SamlException('%s' % result['status']['message'])
		return result
	except: #saml 2
		data = b64decode(token)
		root = ET.fromstring(data)
		cert = root.find('.//{http://www.w3.org/2000/09/xmldsig#}X509Certificate').text
		try:
			assertion_data = xmldsig(data).verify(x509_cert=cert)
		except:
			raise SamlException('x509 certificate exception')
		return {'saml': data}
Esempio n. 14
0
def get_saml(request, token):
    try:
        # Fetch SAML 1.2 info
        AI = settings.SAML_1['AUTH']
        client = Client(AI['wsdl'],
                        username=AI['login'],
                        password=AI['password'])
        ipaddr = request.META.get('REMOTE_ADDR')
        result = client.service.generateSAMLFromToken(token, ipaddr)

        if result['status']['message'] != 'Success':
            raise SamlException('%s' % result['status']['message'])
        return result
    except:  #saml 2
        data = b64decode(token)
        root = ET.fromstring(data)
        cert = root.find(
            './/{http://www.w3.org/2000/09/xmldsig#}X509Certificate').text
        try:
            assertion_data = xmldsig(data).verify(x509_cert=cert)
        except:
            raise SamlException('x509 certificate exception')
        return {'saml': data}
Esempio n. 15
0
                        help="Path to certificate file to validate metadata file with",
                        metavar="certificate_file",
                        type=argparse.FileType("r"))

    args = parser.parse_args()

    md_data = args.metadata_file.read()

    if args.verify_with:

        from cryptography.exceptions import InvalidSignature
        from signxml import xmldsig

        cert = args.verify_with.read()
        try:
            xmldsig(md_data).verify(x509_cert=cert)
        except InvalidSignature:
            print("Metadata signature invalid", file=sys.stderr)
            sys.exit(2)

    md = FederationMetadata(md_data)
    idps = md.idps_matching_scope(args.scope)

    print("Found %d IDP(s) matching scope '%s'" % (len(idps), args.scope), file=sys.stderr)
    for idp in idps:
        display_name = idp.display_name()
        print(display_name, file=sys.stderr)
        locations = idp.ecp_sso_locations()
        if locations:
            for url in locations:
                print("%s: %s" % (display_name, url))
Esempio n. 16
0
def login_island():
    try:
        if 'token' not in request.form:
            raise BadRequest(
                gettext(
                    'Ógilt svar frá innskráningarþjónustu. Innskráningarlykil vantar.'
                ))

        token = request.form['token']

        try:
            token_decoded = base64.b64decode(token)
        except TypeError:
            raise BadRequest(
                gettext(
                    'Ógilt svar frá innskráningarþjónustu. Ógildur innskráningarlykill.'
                ))

        #
        # Sannreyna undirskrift á skírteini.
        #
        signature_object = xmldsig(token_decoded)

        try:
            assertion_data = signature_object.verify(ca_pem_file=os.path.join(
                auth.root_path, 'cert', 'Oll_kedjan.pem'))
        except InvalidSignature:
            raise BadRequest(
                gettext(
                    'Ógilt svar frá innskráningarþjónustu. Undirskrift stenst ekki sannreyningu.'
                ))

        root = ElementTree.fromstring(token_decoded)

        #
        # Gera það sama og í dæmunum í leiðbeiningum. Sannreyna að common name á
        # issuer á skírteininu sé frá þjóðskrá og að serial númer á subjecti sé
        # einnig rétt.
        #
        node_list = root.findall(
            '{http://www.w3.org/2000/09/xmldsig#}Signature')
        cert_list = node_list[0].findall(
            './/{http://www.w3.org/2000/09/xmldsig#}X509Certificate')

        cert = "-----BEGIN CERTIFICATE-----\n{}\n-----END CERTIFICATE-----".format(
            textwrap.fill(cert_list[0].text, 64))

        cert_object = crypto.load_certificate(crypto.FILETYPE_PEM, str(cert))
        cert_subject_sn = cert_object.get_subject().serialNumber
        cert_issuer_cn = cert_object.get_issuer().CN

        if not cert_issuer_cn == 'Traustur bunadur' or not cert_subject_sn == '6503760649':
            raise BadRequest(
                gettext(
                    'Ógilt svar frá innskráningarþjónustu. Undirskrift stenst ekki sannreyningu.'
                ))

        #
        # Sannreyna dagsetningarupplýsingar á svari. Þurfum að sannreyna á móti klukkunni á tölvunni
        # sem er að keyra forritið. Því þarf klukkan á tölvunni að vera stillt á Atlantic/Reykjavík og vera
        # tengd við ntp þjón.
        #
        now = datetime.datetime.now()
        condition_list = root.findall(
            './/{urn:oasis:names:tc:SAML:2.0:assertion}Conditions')
        not_before = condition_list[0].attrib['NotBefore']
        not_on_or_after = condition_list[0].attrib['NotOnOrAfter']

        not_before_date = dateutil_parser.parse(not_before).replace(
            tzinfo=None)
        not_on_or_after_date = dateutil_parser.parse(not_on_or_after).replace(
            tzinfo=None)

        if now < not_before_date:
            raise BadRequest(
                gettext(
                    'Ógilt svar frá innskráningarþjónustu. Svarið er ekki enn orðið gilt.'
                ))

        if now >= not_on_or_after_date:
            raise BadRequest(
                gettext(
                    'Ógilt svar frá innskráningarþjónustu. Svarið er er útrunnið.'
                ))

        #
        # Dagsetningarupplýsingar eru í lagi. Núna getum við sótt allar upplýsingar
        # úr skeytinu, eins og kennitölu, nafn, ip tölu, user agent, ...
        #
        attribute_statement_list = root.findall(
            './/{urn:oasis:names:tc:SAML:2.0:assertion}AttributeStatement')
        attribute_map = dict()

        for attribute in attribute_statement_list[0].findall(
                '{urn:oasis:names:tc:SAML:2.0:assertion}Attribute'):
            attribute_map[attribute.attrib['Name']] = {
                'friendly_name':
                attribute.attrib['FriendlyName'],
                'value':
                attribute.findall(
                    '{urn:oasis:names:tc:SAML:2.0:assertion}AttributeValue')
                [0].text
            }

        #
        # Sannreyna ýmsar upplýsingar eins og IP tölu og vafraupplýsingar.
        #
        if current_app.config['ISLAND_VALIDATE_IP']:
            if 'IPAddress' not in attribute_map or not request.remote_addr == attribute_map[
                    'IPAddress']['value']:
                raise BadRequest(
                    gettext(
                        'Ógilt svar frá innskráningarþjónustu. IP tala stenst ekki sannreyningu.'
                    ))

        if current_app.config['ISLAND_VALIDATE_UA']:
            user_agent = request.headers.get('User-Agent')
            if 'UserAgent' not in attribute_map or not user_agent or not user_agent == attribute_map[
                    'UserAgent']['value']:
                raise BadRequest(
                    gettext('Ógilt svar frá innskráningarþjónustu. '
                            'Vafraupplýsingar standast ekki sannreyningu.'))

        if current_app.config['ISLAND_REQUIRED_AUTHENTICATION'] is not None:
            island_required_auth = current_app.config[
                'ISLAND_REQUIRED_AUTHENTICATION']
            if not isinstance(island_required_auth, list):
                raise EnvironmentError(
                    'Invalid ISLAND_REQUIRED_AUTHENTICATION.')

            authid_ok = False
            authentication = attribute_map['Authentication']['value']
            for required_authid in island_required_auth:
                authid_ok = True if authid_ok else authentication == required_authid

            if not authid_ok:
                raise BadRequest(
                    gettext('Ógilt auðkenning notanda. '
                            'Leyfðar innskráningarleiðir eru: {}.').format(
                                ', '.join(island_required_auth)))

        #
        # Allt er í lagi. Skráum notanda inn. Hér myndum við vanalega sækja notanda úr gagnagrunni
        # og skrá hann inn eða búa hann til þegar hann er ekki til. Í þessu dæmi búum við bara til
        # notanda sem er ekki tengdur gagnagrunni og setjum hann í session.
        #
        # Við erum líka með nafn notanda í attribute_map.
        #
        user = IslykillUser(ssn=attribute_map['UserSSN']['value'])

        login_user(user)

        # Ath. Samkvæmt Flask Login þá ætti að sannreyna 'next' ef það er gefið upp.
        return redirect(request.args.get('next') or url_for('secure.secure'))
    except BadRequest as e:
        error_list = [
            e.description,
        ]

    return render_template('auth/login_failed.html', error_list=error_list)
Esempio n. 17
0
from lxml import etree
import signxml
from signxml import xmldsig

cert = open("cert.pem").read()
key = open("key.pem", "rb").read()

root = etree.parse('texte.xml').getroot()
signer = xmldsig(root, digest_algorithm="sha1")
signer.sign(method=signxml.methods.enveloped, key=key, cert=cert,
            algorithm="rsa-sha1", c14n_algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315',
            reference_uri='#NFe41150715380524000122651010000000271333611649')
#verified_data = signer.verify(require_x509=True, ca_pem_file="cert.pem")
e = etree.tostring(signer.data)
open("testesig.xml", "wb").write(e)

Esempio n. 18
0
from lxml import etree
import signxml
from signxml import xmldsig

cert = open("cert.pem").read()
key = open("key.pem", "rb").read()

root = etree.parse('texte.xml').getroot()
signer = xmldsig(root, digest_algorithm="sha1")
signer.sign(method=signxml.methods.enveloped,
            key=key,
            cert=cert,
            algorithm="rsa-sha1",
            c14n_algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315',
            reference_uri='#NFe41150715380524000122651010000000271333611649')
#verified_data = signer.verify(require_x509=True, ca_pem_file="cert.pem")
e = etree.tostring(signer.data)
open("testesig.xml", "wb").write(e)
Esempio n. 19
0
def login_island():
    try:
        if 'token' not in request.form:
            raise BadRequest(gettext('Ógilt svar frá innskráningarþjónustu. Innskráningarlykil vantar.'))

        token = request.form['token']

        try:
            token_decoded = base64.b64decode(token)
        except TypeError:
            raise BadRequest(gettext('Ógilt svar frá innskráningarþjónustu. Ógildur innskráningarlykill.'))

        #
        # Sannreyna undirskrift á skírteini.
        #
        signature_object = xmldsig(token_decoded)

        try:
            assertion_data = signature_object.verify(ca_pem_file=os.path.join(auth.root_path, 'cert', 'Oll_kedjan.pem'))
        except InvalidSignature:
            raise BadRequest(gettext('Ógilt svar frá innskráningarþjónustu. Undirskrift stenst ekki sannreyningu.'))

        root = ElementTree.fromstring(token_decoded)

        #
        # Gera það sama og í dæmunum í leiðbeiningum. Sannreyna að common name á
        # issuer á skírteininu sé frá þjóðskrá og að serial númer á subjecti sé
        # einnig rétt.
        #
        node_list = root.findall('{http://www.w3.org/2000/09/xmldsig#}Signature')
        cert_list = node_list[0].findall('.//{http://www.w3.org/2000/09/xmldsig#}X509Certificate')

        cert = "-----BEGIN CERTIFICATE-----\n{}\n-----END CERTIFICATE-----".format(textwrap.fill(cert_list[0].text, 64))

        cert_object = crypto.load_certificate(crypto.FILETYPE_PEM, str(cert))
        cert_subject_sn = cert_object.get_subject().serialNumber
        cert_issuer_cn = cert_object.get_issuer().CN

        if not cert_issuer_cn == 'Traustur bunadur' or not cert_subject_sn == '6503760649':
            raise BadRequest(gettext('Ógilt svar frá innskráningarþjónustu. Undirskrift stenst ekki sannreyningu.'))

        #
        # Sannreyna dagsetningarupplýsingar á svari. Þurfum að sannreyna á móti klukkunni á tölvunni
        # sem er að keyra forritið. Því þarf klukkan á tölvunni að vera stillt á Atlantic/Reykjavík og vera
        # tengd við ntp þjón.
        #
        now = datetime.datetime.now()
        condition_list = root.findall('.//{urn:oasis:names:tc:SAML:2.0:assertion}Conditions')
        not_before = condition_list[0].attrib['NotBefore']
        not_on_or_after = condition_list[0].attrib['NotOnOrAfter']

        not_before_date = dateutil_parser.parse(not_before).replace(tzinfo=None)
        not_on_or_after_date = dateutil_parser.parse(not_on_or_after).replace(tzinfo=None)

        if now < not_before_date:
            raise BadRequest(gettext('Ógilt svar frá innskráningarþjónustu. Svarið er ekki enn orðið gilt.'))

        if now >= not_on_or_after_date:
            raise BadRequest(gettext('Ógilt svar frá innskráningarþjónustu. Svarið er er útrunnið.'))

        #
        # Dagsetningarupplýsingar eru í lagi. Núna getum við sótt allar upplýsingar
        # úr skeytinu, eins og kennitölu, nafn, ip tölu, user agent, ...
        #
        attribute_statement_list = root.findall('.//{urn:oasis:names:tc:SAML:2.0:assertion}AttributeStatement')
        attribute_map = dict()

        for attribute in attribute_statement_list[0].findall('{urn:oasis:names:tc:SAML:2.0:assertion}Attribute'):
            attribute_map[attribute.attrib['Name']] = {
                'friendly_name': attribute.attrib['FriendlyName'],
                'value': attribute.findall('{urn:oasis:names:tc:SAML:2.0:assertion}AttributeValue')[0].text
            }

        #
        # Sannreyna ýmsar upplýsingar eins og IP tölu og vafraupplýsingar.
        #
        if current_app.config['ISLAND_VALIDATE_IP']:
            if 'IPAddress' not in attribute_map or not request.remote_addr == attribute_map['IPAddress']['value']:
                raise BadRequest(gettext('Ógilt svar frá innskráningarþjónustu. IP tala stenst ekki sannreyningu.'))

        if current_app.config['ISLAND_VALIDATE_UA']:
            user_agent = request.headers.get('User-Agent')
            if 'UserAgent' not in attribute_map or not user_agent or not user_agent == attribute_map['UserAgent']['value']:
                raise BadRequest(gettext('Ógilt svar frá innskráningarþjónustu. '
                                         'Vafraupplýsingar standast ekki sannreyningu.'))

        if current_app.config['ISLAND_REQUIRED_AUTHENTICATION'] is not None:
            island_required_auth = current_app.config['ISLAND_REQUIRED_AUTHENTICATION']
            if not isinstance(island_required_auth, list):
                raise EnvironmentError('Invalid ISLAND_REQUIRED_AUTHENTICATION.')

            authid_ok = False
            authentication = attribute_map['Authentication']['value']
            for required_authid in island_required_auth:
                authid_ok = True if authid_ok else authentication == required_authid

            if not authid_ok:
                raise BadRequest(gettext('Ógilt auðkenning notanda. '
                                         'Leyfðar innskráningarleiðir eru: {}.').format(', '.join(island_required_auth)))

        #
        # Allt er í lagi. Skráum notanda inn. Hér myndum við vanalega sækja notanda úr gagnagrunni
        # og skrá hann inn eða búa hann til þegar hann er ekki til. Í þessu dæmi búum við bara til
        # notanda sem er ekki tengdur gagnagrunni og setjum hann í session.
        #
        # Við erum líka með nafn notanda í attribute_map.
        #
        user = IslykillUser(ssn=attribute_map['UserSSN']['value'])

        login_user(user)

        # Ath. Samkvæmt Flask Login þá ætti að sannreyna 'next' ef það er gefið upp.
        return redirect(request.args.get('next') or url_for('secure.secure'))
    except BadRequest as e:
        error_list = [e.description, ]

    return render_template('auth/login_failed.html', error_list=error_list)