You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
3.7 KiB

  1. From 4910098653e356f814924663b4ddf71c971a71d6 Mon Sep 17 00:00:00 2001
  2. From: Emeric Brun <ebrun@haproxy.com>
  3. Date: Tue, 24 Jun 2014 18:26:41 +0200
  4. Subject: [PATCH 2/6] BUG/MINOR: ssl: Fix external function in order not to
  5. return a pointer on an internal trash buffer.
  6. 'ssl_sock_get_common_name' applied to a connection was also renamed
  7. 'ssl_sock_get_remote_common_name'. Currently, this function is only used
  8. with protocol PROXYv2 to retrieve the client certificate's common name.
  9. A further usage could be to retrieve the server certificate's common name
  10. on an outgoing connection.
  11. (cherry picked from commit 0abf836ecb32767fa1f9ad598f3e236e073491bd)
  12. ---
  13. include/proto/ssl_sock.h | 2 +-
  14. src/connection.c | 5 ++---
  15. src/ssl_sock.c | 23 +++++++++++------------
  16. 3 files changed, 14 insertions(+), 16 deletions(-)
  17. diff --git a/include/proto/ssl_sock.h b/include/proto/ssl_sock.h
  18. index 0902fde..3e111cd 100644
  19. --- a/include/proto/ssl_sock.h
  20. +++ b/include/proto/ssl_sock.h
  21. @@ -52,7 +52,7 @@ const char *ssl_sock_get_cipher_name(struct connection *conn);
  22. const char *ssl_sock_get_proto_version(struct connection *conn);
  23. char *ssl_sock_get_version(struct connection *conn);
  24. int ssl_sock_get_cert_used(struct connection *conn);
  25. -char *ssl_sock_get_common_name(struct connection *conn);
  26. +int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *out);
  27. unsigned int ssl_sock_get_verify_result(struct connection *conn);
  28. #ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
  29. int ssl_sock_update_ocsp_response(struct chunk *ocsp_response, char **err);
  30. diff --git a/src/connection.c b/src/connection.c
  31. index 0b154d8..20a911b 100644
  32. --- a/src/connection.c
  33. +++ b/src/connection.c
  34. @@ -682,9 +682,8 @@ int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connec
  35. tlv->verify = htonl(ssl_sock_get_verify_result(remote));
  36. }
  37. if (srv->pp_opts & SRV_PP_V2_SSL_CN) {
  38. - value = ssl_sock_get_common_name(remote);
  39. - if (value) {
  40. - tlv_len = make_tlv(&buf[ret+ssl_tlv_len], (buf_len - ret - ssl_tlv_len), PP2_TYPE_SSL_CN, strlen(value), value);
  41. + if (ssl_sock_get_remote_common_name(remote, &trash) > 0) {
  42. + tlv_len = make_tlv(&buf[ret+ssl_tlv_len], (buf_len - ret - ssl_tlv_len), PP2_TYPE_SSL_CN, trash.len, trash.str);
  43. ssl_tlv_len += tlv_len;
  44. }
  45. }
  46. diff --git a/src/ssl_sock.c b/src/ssl_sock.c
  47. index 328b978..375225d 100644
  48. --- a/src/ssl_sock.c
  49. +++ b/src/ssl_sock.c
  50. @@ -2654,21 +2654,25 @@ char *ssl_sock_get_version(struct connection *conn)
  51. return (char *)SSL_get_version(conn->xprt_ctx);
  52. }
  53. -/* returns common name, NULL terminated, from client certificate, or NULL if none */
  54. -char *ssl_sock_get_common_name(struct connection *conn)
  55. +/* Extract peer certificate's common name into the chunk dest
  56. + * Returns
  57. + * the len of the extracted common name
  58. + * or 0 if no CN found in DN
  59. + * or -1 on error case (i.e. no peer certificate)
  60. + */
  61. +int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *dest)
  62. {
  63. X509 *crt = NULL;
  64. X509_NAME *name;
  65. - struct chunk *cn_trash;
  66. const char find_cn[] = "CN";
  67. const struct chunk find_cn_chunk = {
  68. .str = (char *)&find_cn,
  69. .len = sizeof(find_cn)-1
  70. };
  71. - char *result = NULL;
  72. + int result = -1;
  73. if (!ssl_sock_is_ssl(conn))
  74. - return NULL;
  75. + goto out;
  76. /* SSL_get_peer_certificate, it increase X509 * ref count */
  77. crt = SSL_get_peer_certificate(conn->xprt_ctx);
  78. @@ -2679,13 +2683,8 @@ char *ssl_sock_get_common_name(struct connection *conn)
  79. if (!name)
  80. goto out;
  81. - cn_trash = get_trash_chunk();
  82. - if (ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, cn_trash) <= 0)
  83. - goto out;
  84. - cn_trash->str[cn_trash->len] = '\0';
  85. - result = cn_trash->str;
  86. -
  87. - out:
  88. + result = ssl_sock_get_dn_entry(name, &find_cn_chunk, 1, dest);
  89. +out:
  90. if (crt)
  91. X509_free(crt);
  92. --
  93. 1.8.5.5