cproxy.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * Header for the interaction between proxy.c and cproxy.c. Separated
  3. * from proxy.h proper so that testcrypt can include it conveniently.
  4. */
  5. extern const bool socks5_chap_available;
  6. strbuf *chap_response(ptrlen challenge, ptrlen password);
  7. extern const bool http_digest_available;
  8. /*
  9. * List macro for the various hash functions defined for HTTP Digest.
  10. *
  11. * Of these, MD5 is the original one; SHA-256 is unambiguous; but
  12. * SHA-512-256 seems to be controversial.
  13. *
  14. * RFC 7616 doesn't provide a normative reference, or any text
  15. * explaining what they mean by it. They apparently expect you to
  16. * already know. The problem with that is that there are two plausible
  17. * things they _might_ have meant:
  18. *
  19. * 1. Ordinary SHA-512, truncated to 256 bits by discarding the
  20. * second half of the hash output, per FIPS 180-4 section 7 (which
  21. * says that in general it's OK to truncate hash functions like
  22. * that if you need to). FIPS 180-4 assigns no particular specific
  23. * spelling to this kind of truncated hash.
  24. *
  25. * 2. The same except that the initial state of the SHA-512 algorithm
  26. * is reset to a different 512-bit vector to ensure that it's a
  27. * distinguishable hash function in its own right, per FIPS 180-4
  28. * section 6.7 (which in turn refers to section 5.3.6.2 for the
  29. * actual initial values). FIPS 180-4 spells this "SHA-512/256".
  30. *
  31. * The text of RFC 7616 is totally silent as to which of these they
  32. * meant. Their spelling is inconsistent: the protocol identifier is
  33. * "SHA-512-256", but in some places in the RFC they say
  34. * "SHA-512/256", matching FIPS's spelling for the hash in option 2
  35. * above. On the other hand, the example authentication exchange in
  36. * section 3.9.2 of the RFC contains hashes that are consistent with
  37. * option 1 above (a truncation of plain SHA-512).
  38. *
  39. * Erratum 4897, https://www.rfc-editor.org/errata/eid4897, points out
  40. * this ambiguity, and suggests correcting the example exchange to be
  41. * consistent with option 2. However, as of 2021-11-27, that erratum
  42. * is shown on the RFC Editor website in state "Reported", with no
  43. * response (positive _or_ negative) from the RFC authors or anyone
  44. * else. (And it was reported in 2016, so it's not as if they haven't
  45. * had time.)
  46. *
  47. * So, which hash should we implement? Perhaps there's a consensus
  48. * among existing implementations in the wild?
  49. *
  50. * I rigged up an HTTP server to present a SHA-512-256 Digest auth
  51. * request, and tried various HTTP clients against it. The only HTTP
  52. * client I found that accepts 'algorithm="SHA-512-256"' and sends
  53. * back an auth attempt quoting the same hash is curl - and curl,
  54. * bizarrely, seems to treat "SHA-512-256" as _neither_ of the above
  55. * options, but as simply an alias for SHA-256!
  56. *
  57. * Therefore, I think the only safe answer is to refuse to support
  58. * that hash at all: it's too confusing.
  59. *
  60. * However, I keep it in the list of hashes here, so that we can check
  61. * the test case from RFC 7616, because that test case is also the
  62. * only test of username hashing. So we reject it in proxy/http.c, but
  63. * accept it in the internal function http_digest_response(), and
  64. * treat it as option 1 (truncated SHA-512).
  65. *
  66. * Therefore, the parameters to each invocation of X in the following
  67. * list macro are:
  68. *
  69. * - internal enum id for the hash
  70. * - protocol identifier string
  71. * - algorithm to use for computing it (as a const ssh_hashalg *)
  72. * - length to truncate the output to
  73. * - whether we accept it in http.c or not.
  74. *
  75. * Finally, the ordering of the accepted hashes is our preference
  76. * order among them if the server offers a choice.
  77. */
  78. #define HTTP_DIGEST_HASHES(X) \
  79. X(HTTP_DIGEST_MD5, "MD5", &ssh_md5, 128, true) \
  80. X(HTTP_DIGEST_SHA256, "SHA-256", &ssh_sha256, 256, true) \
  81. X(HTTP_DIGEST_SHA512_256, "SHA-512-256", &ssh_sha512, 256, false) \
  82. /* end of list */
  83. typedef enum HttpDigestHash {
  84. #define DECL_ENUM(id, str, alg, bits, accepted) id,
  85. HTTP_DIGEST_HASHES(DECL_ENUM)
  86. #undef DECL_ENUM
  87. N_HTTP_DIGEST_HASHES
  88. } HttpDigestHash;
  89. extern const char *const httphashnames[];
  90. extern const bool httphashaccepted[];
  91. void http_digest_response(BinarySink *bs, ptrlen username, ptrlen password,
  92. ptrlen realm, ptrlen method, ptrlen uri, ptrlen qop,
  93. ptrlen nonce, ptrlen opaque, uint32_t nonce_count,
  94. HttpDigestHash hash, bool hash_username);