| | 172 | static void tls_get_client_cert (CONNECTION* conn) |
| | 173 | { |
| | 174 | tlssockdata *data = conn->sockdata; |
| | 175 | const gnutls_datum_t* crtdata; |
| | 176 | gnutls_x509_crt_t clientcrt; |
| | 177 | char* dn; |
| | 178 | char* cn; |
| | 179 | char* cnend; |
| | 180 | size_t dnlen; |
| | 181 | |
| | 182 | /* get our cert CN if we have one */ |
| | 183 | if (!(crtdata = gnutls_certificate_get_ours (data->state))) |
| | 184 | return; |
| | 185 | |
| | 186 | if (gnutls_x509_crt_init (&clientcrt) < 0) |
| | 187 | { |
| | 188 | dprint (1, (debugfile, "Failed to init gnutls crt\n")); |
| | 189 | return; |
| | 190 | } |
| | 191 | if (gnutls_x509_crt_import (clientcrt, crtdata, GNUTLS_X509_FMT_DER) < 0) |
| | 192 | { |
| | 193 | dprint (1, (debugfile, "Failed to import gnutls client crt\n")); |
| | 194 | goto err_crt; |
| | 195 | } |
| | 196 | /* get length of DN */ |
| | 197 | dnlen = 0; |
| | 198 | gnutls_x509_crt_get_dn (clientcrt, NULL, &dnlen); |
| | 199 | if (!(dn = calloc (1, dnlen))) |
| | 200 | { |
| | 201 | dprint (1, (debugfile, "could not allocate DN\n")); |
| | 202 | goto err_crt; |
| | 203 | } |
| | 204 | gnutls_x509_crt_get_dn (clientcrt, dn, &dnlen); |
| | 205 | dprint (2, (debugfile, "client certificate DN: %s\n", dn)); |
| | 206 | |
| | 207 | /* extract CN to use as external user name */ |
| | 208 | if (!(cn = strstr (dn, "CN="))) |
| | 209 | { |
| | 210 | dprint (1, (debugfile, "no CN found in DN\n")); |
| | 211 | goto err_dn; |
| | 212 | } |
| | 213 | cn += 3; |
| | 214 | |
| | 215 | if ((cnend = strstr (dn, ",EMAIL="))) |
| | 216 | *cnend = '\0'; |
| | 217 | |
| | 218 | dprint (2, (debugfile, "client CN: %s\n", cn)); |
| | 219 | |
| | 220 | err_dn: |
| | 221 | FREE (&dn); |
| | 222 | err_crt: |
| | 223 | gnutls_x509_crt_deinit (clientcrt); |
| | 224 | } |
| | 225 | |