(out: OutputBuffer, alg_db: Dict[str, Dict[str, List[List[Optional[str]]]]], alg_type: str, alg_name: str, unknown_algs: List[str], program_retval: int, alg_max_len: int = 0, host_keys: Optional[Dict[str, Dict[str, Union[bytes, str, int]]]] = None, dh_modulus_sizes: Optional[Dict[str, int]] = None)
| 150 | |
| 151 | |
| 152 | def output_algorithm(out: OutputBuffer, alg_db: Dict[str, Dict[str, List[List[Optional[str]]]]], alg_type: str, alg_name: str, unknown_algs: List[str], program_retval: int, alg_max_len: int = 0, host_keys: Optional[Dict[str, Dict[str, Union[bytes, str, int]]]] = None, dh_modulus_sizes: Optional[Dict[str, int]] = None) -> int: # pylint: disable=too-many-arguments |
| 153 | prefix = '(' + alg_type + ') ' |
| 154 | if alg_max_len == 0: |
| 155 | alg_max_len = len(alg_name) |
| 156 | padding = '' if out.batch else ' ' * (alg_max_len - len(alg_name)) |
| 157 | |
| 158 | # If this is an RSA host key or DH GEX, append the size to its name and fix |
| 159 | # the padding. |
| 160 | alg_name_with_size = None |
| 161 | if (dh_modulus_sizes is not None) and (alg_name in dh_modulus_sizes): |
| 162 | alg_name_with_size = '%s (%u-bit)' % (alg_name, dh_modulus_sizes[alg_name]) |
| 163 | padding = padding[0:-11] |
| 164 | elif (host_keys is not None) and (alg_name in host_keys): |
| 165 | hostkey_size = cast(int, host_keys[alg_name]['hostkey_size']) |
| 166 | ca_key_type = cast(str, host_keys[alg_name]['ca_key_type']) |
| 167 | ca_key_size = cast(int, host_keys[alg_name]['ca_key_size']) |
| 168 | |
| 169 | # If this is an RSA variant, just print "RSA". |
| 170 | if ca_key_type in HostKeyTest.RSA_FAMILY: |
| 171 | ca_key_type = "RSA" |
| 172 | |
| 173 | if len(ca_key_type) > 0 and ca_key_size > 0: |
| 174 | alg_name_with_size = '%s (%u-bit cert/%u-bit %s CA)' % (alg_name, hostkey_size, ca_key_size, ca_key_type) |
| 175 | padding = padding[0:-15] |
| 176 | elif alg_name in HostKeyTest.RSA_FAMILY: |
| 177 | alg_name_with_size = '%s (%u-bit)' % (alg_name, hostkey_size) |
| 178 | padding = padding[0:-11] |
| 179 | |
| 180 | # If this is a kex algorithm and starts with 'gss-', then normalize its name (i.e.: 'gss-gex-sha1-vz8J1E9PzLr8b1K+0remTg==' => 'gss-gex-sha1-*'). The base64 field can vary, so we'll convert it to the wildcard that our database uses and we'll just resume doing a straight match like all other algorithm names. |
| 181 | alg_name_original = alg_name |
| 182 | if alg_type == 'kex' and alg_name.startswith('gss-'): |
| 183 | last_dash = alg_name.rindex('-') |
| 184 | alg_name = "%s-*" % alg_name[0:last_dash] |
| 185 | |
| 186 | texts = [] |
| 187 | if len(alg_name.strip()) == 0: |
| 188 | return program_retval |
| 189 | alg_name_native = Utils.to_text(alg_name) |
| 190 | if alg_name_native in alg_db[alg_type]: |
| 191 | alg_desc = alg_db[alg_type][alg_name_native] |
| 192 | ldesc = len(alg_desc) |
| 193 | for idx, level in enumerate(['fail', 'warn', 'info']): |
| 194 | if level == 'info': |
| 195 | versions = alg_desc[0] |
| 196 | since_text = Algorithm.get_since_text(versions) |
| 197 | if since_text is not None and len(since_text) > 0: |
| 198 | texts.append((level, since_text)) |
| 199 | idx = idx + 1 |
| 200 | if ldesc > idx: |
| 201 | for t in alg_desc[idx]: |
| 202 | if t is None: |
| 203 | continue |
| 204 | texts.append((level, t)) |
| 205 | if len(texts) == 0: |
| 206 | texts.append(('info', '')) |
| 207 | else: |
| 208 | texts.append(('warn', 'unknown algorithm')) |
| 209 | unknown_algs.append(alg_name) |
no test coverage detected