quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

translate_ciphers.py (5865B)


      1 #!/usr/bin/env python3
      2 
      3 # translate_ciphers.py
      4 #
      5 # Copyright The Mbed TLS Contributors
      6 # SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
      7 
      8 """
      9 Translate standard ciphersuite names to GnuTLS, OpenSSL and Mbed TLS standards.
     10 
     11 To test the translation functions run:
     12 python3 -m unittest translate_cipher.py
     13 """
     14 
     15 import re
     16 import argparse
     17 import unittest
     18 
     19 class TestTranslateCiphers(unittest.TestCase):
     20     """
     21     Ensure translate_ciphers.py translates and formats ciphersuite names
     22     correctly
     23     """
     24     def test_translate_all_cipher_names(self):
     25         """
     26         Translate standard ciphersuite names to GnuTLS, OpenSSL and
     27         Mbed TLS counterpart. Use only a small subset of ciphers
     28         that exercise each step of the translation functions
     29         """
     30         ciphers = [
     31             ("TLS_ECDHE_ECDSA_WITH_NULL_SHA",
     32              "+ECDHE-ECDSA:+NULL:+SHA1",
     33              "ECDHE-ECDSA-NULL-SHA",
     34              "TLS-ECDHE-ECDSA-WITH-NULL-SHA"),
     35             ("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
     36              "+ECDHE-ECDSA:+AES-128-GCM:+AEAD",
     37              "ECDHE-ECDSA-AES128-GCM-SHA256",
     38              "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256"),
     39             ("TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
     40              "+DHE-RSA:+3DES-CBC:+SHA1",
     41              "EDH-RSA-DES-CBC3-SHA",
     42              "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA"),
     43             ("TLS_RSA_WITH_AES_256_CBC_SHA",
     44              "+RSA:+AES-256-CBC:+SHA1",
     45              "AES256-SHA",
     46              "TLS-RSA-WITH-AES-256-CBC-SHA"),
     47             ("TLS_PSK_WITH_3DES_EDE_CBC_SHA",
     48              "+PSK:+3DES-CBC:+SHA1",
     49              "PSK-3DES-EDE-CBC-SHA",
     50              "TLS-PSK-WITH-3DES-EDE-CBC-SHA"),
     51             ("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
     52              None,
     53              "ECDHE-ECDSA-CHACHA20-POLY1305",
     54              "TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256"),
     55             ("TLS_ECDHE_ECDSA_WITH_AES_128_CCM",
     56              "+ECDHE-ECDSA:+AES-128-CCM:+AEAD",
     57              None,
     58              "TLS-ECDHE-ECDSA-WITH-AES-128-CCM"),
     59             ("TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384",
     60              None,
     61              "ECDHE-ARIA256-GCM-SHA384",
     62              "TLS-ECDHE-RSA-WITH-ARIA-256-GCM-SHA384"),
     63         ]
     64 
     65         for s, g_exp, o_exp, m_exp in ciphers:
     66 
     67             if g_exp is not None:
     68                 g = translate_gnutls(s)
     69                 self.assertEqual(g, g_exp)
     70 
     71             if o_exp is not None:
     72                 o = translate_ossl(s)
     73                 self.assertEqual(o, o_exp)
     74 
     75             if m_exp is not None:
     76                 m = translate_mbedtls(s)
     77                 self.assertEqual(m, m_exp)
     78 
     79 def translate_gnutls(s_cipher):
     80     """
     81     Translate s_cipher from standard ciphersuite naming convention
     82     and return the GnuTLS naming convention
     83     """
     84 
     85     # Replace "_" with "-" to handle ciphersuite names based on Mbed TLS
     86     # naming convention
     87     s_cipher = s_cipher.replace("_", "-")
     88 
     89     s_cipher = re.sub(r'\ATLS-', '+', s_cipher)
     90     s_cipher = s_cipher.replace("-WITH-", ":+")
     91     s_cipher = s_cipher.replace("-EDE", "")
     92 
     93     # SHA in Mbed TLS == SHA1 GnuTLS,
     94     # if the last 3 chars are SHA append 1
     95     if s_cipher[-3:] == "SHA":
     96         s_cipher = s_cipher+"1"
     97 
     98     # CCM or CCM-8 should be followed by ":+AEAD"
     99     # Replace "GCM:+SHAxyz" with "GCM:+AEAD"
    100     if "CCM" in s_cipher or "GCM" in s_cipher:
    101         s_cipher = re.sub(r"GCM-SHA\d\d\d", "GCM", s_cipher)
    102         s_cipher = s_cipher+":+AEAD"
    103 
    104     # Replace the last "-" with ":+"
    105     else:
    106         index = s_cipher.rindex("-")
    107         s_cipher = s_cipher[:index] + ":+" + s_cipher[index+1:]
    108 
    109     return s_cipher
    110 
    111 def translate_ossl(s_cipher):
    112     """
    113     Translate s_cipher from standard ciphersuite naming convention
    114     and return the OpenSSL naming convention
    115     """
    116 
    117     # Replace "_" with "-" to handle ciphersuite names based on Mbed TLS
    118     # naming convention
    119     s_cipher = s_cipher.replace("_", "-")
    120 
    121     s_cipher = re.sub(r'^TLS-', '', s_cipher)
    122     s_cipher = s_cipher.replace("-WITH", "")
    123 
    124     # Remove the "-" from "ABC-xyz"
    125     s_cipher = s_cipher.replace("AES-", "AES")
    126     s_cipher = s_cipher.replace("CAMELLIA-", "CAMELLIA")
    127     s_cipher = s_cipher.replace("ARIA-", "ARIA")
    128 
    129     # Remove "RSA" if it is at the beginning
    130     s_cipher = re.sub(r'^RSA-', r'', s_cipher)
    131 
    132     # For all circumstances outside of PSK
    133     if "PSK" not in s_cipher:
    134         s_cipher = s_cipher.replace("-EDE", "")
    135         s_cipher = s_cipher.replace("3DES-CBC", "DES-CBC3")
    136 
    137         # Remove "CBC" if it is not prefixed by DES
    138         s_cipher = re.sub(r'(?<!DES-)CBC-', r'', s_cipher)
    139 
    140     # ECDHE-RSA-ARIA does not exist in OpenSSL
    141     s_cipher = s_cipher.replace("ECDHE-RSA-ARIA", "ECDHE-ARIA")
    142 
    143     # POLY1305 should not be followed by anything
    144     if "POLY1305" in s_cipher:
    145         index = s_cipher.rindex("POLY1305")
    146         s_cipher = s_cipher[:index+8]
    147 
    148     # If DES is being used, Replace DHE with EDH
    149     if "DES" in s_cipher and "DHE" in s_cipher and "ECDHE" not in s_cipher:
    150         s_cipher = s_cipher.replace("DHE", "EDH")
    151 
    152     return s_cipher
    153 
    154 def translate_mbedtls(s_cipher):
    155     """
    156     Translate s_cipher from standard ciphersuite naming convention
    157     and return Mbed TLS ciphersuite naming convention
    158     """
    159 
    160     # Replace "_" with "-"
    161     s_cipher = s_cipher.replace("_", "-")
    162 
    163     return s_cipher
    164 
    165 def format_ciphersuite_names(mode, names):
    166     t = {"g": translate_gnutls,
    167          "o": translate_ossl,
    168          "m": translate_mbedtls
    169         }[mode]
    170     return " ".join(c + '=' + t(c) for c in names)
    171 
    172 def main(target, names):
    173     print(format_ciphersuite_names(target, names))
    174 
    175 if __name__ == "__main__":
    176     PARSER = argparse.ArgumentParser()
    177     PARSER.add_argument('target', metavar='TARGET', choices=['o', 'g', 'm'])
    178     PARSER.add_argument('names', metavar='NAMES', nargs='+')
    179     ARGS = PARSER.parse_args()
    180     main(ARGS.target, ARGS.names)