diff --git a/src/authentic2/saml/saml2utils.py b/src/authentic2/saml/saml2utils.py index 42d93306a..f3a8d645c 100644 --- a/src/authentic2/saml/saml2utils.py +++ b/src/authentic2/saml/saml2utils.py @@ -57,13 +57,6 @@ def bool2xs(boolean): raise TypeError() -def int_to_b64(i): - h = hex(i)[2:].strip('L') - if len(h) % 2 == 1: - h = '0' + h - return base64.b64encode(binascii.unhexlify(h)) - - def keyinfo(tb, key): tb.pushNamespace(lasso.DS_HREF) tb.start('KeyInfo', {}) @@ -78,10 +71,14 @@ def keyinfo(tb, key): tb.start('KeyValue', {}) tb.start('RSAKeyValue', {}) tb.start('Modulus', {}) - tb.data(int_to_b64(x509utils.get_rsa_public_key_modulus(key))) + tb.data( + x509utils.int_to_cryptobinary( + x509utils.get_rsa_public_key_modulus(key))) tb.end('Modulus') tb.start('Exponent', {}) - tb.data(int_to_b64(x509utils.get_rsa_public_key_exponent(key))) + tb.data( + x509utils.int_to_cryptobinary( + x509utils.get_rsa_public_key_exponent(key))) tb.end('Exponent') tb.end('RSAKeyValue') tb.end('KeyValue') diff --git a/src/authentic2/saml/x509utils.py b/src/authentic2/saml/x509utils.py index 1f6e843bf..3c14fe839 100644 --- a/src/authentic2/saml/x509utils.py +++ b/src/authentic2/saml/x509utils.py @@ -162,25 +162,20 @@ def can_generate_rsa_key_pair(): return False -def get_xmldsig_rsa_key_value(publickey): - def int_to_bin(i): - h = hex(i)[2:].strip('L') - if len(h) % 2 == 1: - h = '0' + h - return binascii.unhexlify(h) +def int_to_cryptobinary(integer): + # ref: https://www.w3.org/TR/xmldsig-core1/#sec-CryptoBinary + byte_length = (integer.bit_length() + 7) // 8 + integer_bytes = integer.to_bytes(byte_length, byteorder='big') + return base64.b64encode(integer_bytes).decode('ascii') + +def get_xmldsig_rsa_key_value(publickey): mod = get_rsa_public_key_modulus(publickey) exp = get_rsa_public_key_exponent(publickey) - mod_byte_length = (mod.bit_length() + 7) // 8 - exp_byte_length = (exp.bit_length() + 7) // 8 - mod_bytes = mod.to_bytes(mod_byte_length, byteorder='big') - exp_bytes = exp.to_bytes(exp_byte_length, byteorder='big') - mod_cryptobinary = base64.b64encode(mod_bytes).decode('ascii') - exp_cryptobinary = base64.b64encode(exp_bytes).decode('ascii') return ( '\n\t' '%s\n\t' '%s\n' % ( - mod_cryptobinary, - exp_cryptobinary) - ) + int_to_cryptobinary(mod), + int_to_cryptobinary(exp), + )) diff --git a/tests/test_idp_saml2.py b/tests/test_idp_saml2.py index 572e31de0..182bc38dc 100644 --- a/tests/test_idp_saml2.py +++ b/tests/test_idp_saml2.py @@ -955,3 +955,16 @@ def test_add_attributes_user_ou1_role_ou2(add_attributes_all, user_ou1, role_ou2 'django_user_uuid': set([user_ou1.uuid]), 'is_admin': set(['true']), } + + +def test_metadata_with_openssl_public_key(app, idp, settings): + settings.A2_IDP_SAML2_SIGNATURE_PUBLIC_KEY = '''-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvxFkfPdndlGgQPDZgFGX +brNAc/79PULZBuNdWFHDD9P5hNhZn9Kqm4Cp06Pe/A6u+g5wLnYvbZQcFCgfQAEz +ziJtb3J55OOlB7iMEI/T2AX2WzrUH8QT8NGhABONKU2Gg4XiyeXNhH5R7zdHlUwc +Wq3ZwNbtbY0TVc+n665EbrfV/59xihSqsoFrkmBLH0CoepUXtAzA7WDYn8AzusIu +Mx3n8844pJwgxhTB7Gjuboptlz9Hri8JRdXiVT9OS9Wt69ubcNoM6zuKASmtm48U +uGnhj8v6XwvbjKZrL9kA+xf8ziazZfvvw/VGTm+IVFYB7d1x457jY5zjjXJvNyso +owIDAQAB +-----END PUBLIC KEY-----''' + response = app.get('/idp/saml2/metadata')