Changeset e5bbda4 in mod_gnutls


Ignore:
Timestamp:
Dec 15, 2007, 8:26:01 AM (12 years ago)
Author:
Nokis Mavrogiannopoulos <nmav@…>
Branches:
debian/master, debian/stretch-backports, jessie-backports, master, msva, upstream
Children:
5542bc6
Parents:
d2439b9
git-author:
Nikos Mavrogiannopoulos <nmav@…> (12/15/07 08:26:01)
git-committer:
Nokis Mavrogiannopoulos <nmav@…> (12/15/07 08:26:01)
Message:

Initial support for openpgp keys

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • NEWS

    rd2439b9 re5bbda4  
     1** Version 0.5.0
     2
     3- Added support for OpenPGP keys.
     4
    15** Version 0.4.2 (2007-12-10)
    26
     
    2428
    2529- No longer default paths for RSA and DH parameter files.
     30[5~
  • include/mod_gnutls.h.in

    rd2439b9 re5bbda4  
    3030#include <gcrypt.h>
    3131#include <gnutls/gnutls.h>
     32#include <gnutls/extra.h>
     33#include <gnutls/openpgp.h>
    3234#include <gnutls/x509.h>
    3335
     
    9597    unsigned int certs_x509_num;
    9698    gnutls_x509_privkey_t privkey_x509;
     99    gnutls_openpgp_crt_t cert_pgp; /* A certificate chain */
     100    gnutls_openpgp_privkey_t privkey_pgp;
    97101    int enabled;
    98102    /* whether to send the PEM encoded certificates
     
    109113    const char* srp_tpasswd_conf_file;
    110114    gnutls_x509_crt_t ca_list[MAX_CA_CRTS];
     115    gnutls_openpgp_keyring_t pgp_list;
    111116    unsigned int ca_list_size;
    112117    int client_verify_mode;
     
    255260                             const char *arg);
    256261
     262const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy,
     263                                        const char *arg);
     264
     265const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy,
     266                             const char *arg);
     267
    257268const char *mgs_set_cache(cmd_parms * parms, void *dummy,
    258269                          const char *type, const char* arg);
     
    265276
    266277const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy,
     278                                   const char *arg);
     279
     280const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy,
    267281                                   const char *arg);
    268282
  • src/gnutls_config.c

    rd2439b9 re5bbda4  
    203203}
    204204
     205const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy,
     206                              const char *arg)
     207{
     208    int ret;
     209    gnutls_datum_t data;
     210    const char *file;
     211    apr_pool_t *spool;
     212    mgs_srvconf_rec *sc =
     213        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     214                                                 module_config,
     215                                                 &gnutls_module);
     216    apr_pool_create(&spool, parms->pool);
     217
     218    file = ap_server_root_relative(spool, arg);
     219
     220    if (load_datum_from_file(spool, file, &data) != 0) {
     221        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
     222                            "Certificate '%s'", file);
     223    }
     224
     225    ret = gnutls_openpgp_crt_init( &sc->cert_pgp);
     226    if (ret < 0) {
     227        return apr_psprintf(parms->pool, "GnuTLS: Failed to Init "
     228                            "PGP Certificate: (%d) %s", ret,
     229                            gnutls_strerror(ret));
     230    }
     231     
     232
     233    ret =
     234        gnutls_openpgp_crt_import(sc->cert_pgp, &data, GNUTLS_OPENPGP_FMT_BASE64);
     235    if (ret < 0) {
     236        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
     237                            "PGP Certificate '%s': (%d) %s", file, ret,
     238                            gnutls_strerror(ret));
     239    }
     240
     241    apr_pool_destroy(spool);
     242    return NULL;
     243}
     244
     245const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy,
     246                             const char *arg)
     247{
     248    int ret;
     249    gnutls_datum_t data;
     250    const char *file;
     251    apr_pool_t *spool;
     252    mgs_srvconf_rec *sc =
     253        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     254                                                 module_config,
     255                                                 &gnutls_module);
     256    apr_pool_create(&spool, parms->pool);
     257
     258    file = ap_server_root_relative(spool, arg);
     259
     260    if (load_datum_from_file(spool, file, &data) != 0) {
     261        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
     262                            "Private Key '%s'", file);
     263    }
     264
     265    ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp);
     266    if (ret < 0) {
     267        return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize"
     268                            ": (%d) %s", ret, gnutls_strerror(ret));
     269    }
     270
     271    ret =
     272        gnutls_openpgp_privkey_import(sc->privkey_pgp, &data,
     273                                   GNUTLS_OPENPGP_FMT_BASE64, NULL, 0);
     274    if (ret != 0) {
     275        return apr_psprintf(parms->pool, "GnuTLS: Failed to Import "
     276                            "PGP Private Key '%s': (%d) %s", file, ret,
     277                            gnutls_strerror(ret));
     278    }
     279    apr_pool_destroy(spool);
     280    return NULL;
     281}
     282
     283
    205284const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy,
    206285                                     const char *arg)
     
    351430}
    352431
     432const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy,
     433                                   const char *arg)
     434{
     435    int rv;
     436    const char *file;
     437    apr_pool_t *spool;
     438    gnutls_datum_t data;
     439
     440    mgs_srvconf_rec *sc =
     441        (mgs_srvconf_rec *) ap_get_module_config(parms->server->
     442                                                 module_config,
     443                                                 &gnutls_module);
     444    apr_pool_create(&spool, parms->pool);
     445
     446    file = ap_server_root_relative(spool, arg);
     447
     448    if (load_datum_from_file(spool, file, &data) != 0) {
     449        return apr_psprintf(parms->pool, "GnuTLS: Error Reading "
     450                            "Keyring File '%s'", file);
     451    }
     452
     453    rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data, GNUTLS_OPENPGP_FMT_BASE64);
     454    if (rv < 0) {
     455        return apr_psprintf(parms->pool, "GnuTLS: Failed to load "
     456                            "Keyring File '%s': (%d) %s", file, rv,
     457                            gnutls_strerror(rv));
     458    }
     459
     460    apr_pool_destroy(spool);
     461    return NULL;
     462}
     463
    353464const char *mgs_set_enabled(cmd_parms * parms, void *dummy,
    354465                            const char *arg)
  • src/gnutls_hooks.c

    rd2439b9 re5bbda4  
    3737static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt);
    3838/* use side==0 for server and side==1 for client */
    39 static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert,
     39static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert,
     40                                     int side,
     41                                     int export_certificates_enabled);
     42static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert,
    4043                                     int side,
    4144                                     int export_certificates_enabled);
     
    7073
    7174    ret = gnutls_global_init();
     75    if (ret < 0) /* FIXME: can we print here? */
     76        exit(ret);
     77
     78    ret = gnutls_global_init_extra();
    7279    if (ret < 0) /* FIXME: can we print here? */
    7380        exit(ret);
     
    8895}
    8996
    90 /* We don't support openpgp certificates, yet */
    91 const static int cert_type_prio[2] = { GNUTLS_CRT_X509, 0 };
    92 
    9397static int mgs_select_virtual_server_cb(gnutls_session_t session)
    9498{
     
    96100    mgs_srvconf_rec *tsc;
    97101    int ret;
     102    int cprio[3] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 };
    98103
    99104    ctxt = gnutls_transport_get_ptr(session);
     
    127132     */
    128133    ret = gnutls_priority_set(session, ctxt->sc->priorities);
    129     gnutls_certificate_type_set_priority(session, cert_type_prio);
    130 
     134
     135    /* Do not allow the user to override certificate priorities. We know
     136     * better if the certificate of certain type is enabled. */
     137    if (ctxt->sc->cert_pgp != NULL && ctxt->sc->certs_x509[0] != NULL) {
     138        gnutls_certificate_type_set_priority( session, cprio);
     139    } else if (ctxt->sc->certs_x509[0] != NULL) {
     140        cprio[0] = GNUTLS_CRT_X509;
     141        cprio[1] = 0;
     142        gnutls_certificate_type_set_priority( session, cprio);
     143    } else if (ctxt->sc->cert_pgp != NULL) {
     144        cprio[0] = GNUTLS_CRT_OPENPGP;
     145        cprio[1] = 0;
     146        gnutls_certificate_type_set_priority( session, cprio);
     147    }
    131148
    132149    /* actually it shouldn't fail since we have checked at startup */
     
    144161    ctxt = gnutls_transport_get_ptr(session);
    145162
    146     ret->type = GNUTLS_CRT_X509;
    147     ret->ncerts = ctxt->sc->certs_x509_num;
    148     ret->deinit_all = 0;
    149 
    150     ret->cert.x509 = ctxt->sc->certs_x509;
    151     ret->key.x509 = ctxt->sc->privkey_x509;
    152     return 0;
     163    if (gnutls_certificate_type_get( session) == GNUTLS_CRT_X509) {
     164        ret->type = GNUTLS_CRT_X509;
     165        ret->ncerts = ctxt->sc->certs_x509_num;
     166        ret->deinit_all = 0;
     167
     168        ret->cert.x509 = ctxt->sc->certs_x509;
     169        ret->key.x509 = ctxt->sc->privkey_x509;
     170       
     171        return 0;
     172    } else if (gnutls_certificate_type_get( session) == GNUTLS_CRT_OPENPGP) {
     173        ret->type = GNUTLS_CRT_OPENPGP;
     174        ret->ncerts = 1;
     175        ret->deinit_all = 0;
     176
     177        ret->cert.pgp = ctxt->sc->cert_pgp;
     178        ret->key.pgp = ctxt->sc->privkey_pgp;
     179
     180        return 0;
     181   
     182    }
     183
     184    return GNUTLS_E_INTERNAL_ERROR;
    153185}
    154186
     
    168200 */
    169201static int read_crt_cn(server_rec * s, apr_pool_t * p,
    170                        gnutls_x509_crt cert, char **cert_cn)
     202                       gnutls_x509_crt_t cert, char **cert_cn)
    171203{
    172204    int rv = 0, i;
     
    176208    *cert_cn = NULL;
    177209
     210    data_len = 0;
    178211    rv = gnutls_x509_crt_get_dn_by_oid(cert,
    179212                                       GNUTLS_OID_X520_COMMON_NAME,
     
    187220    } else {                    /* No CN return subject alternative name */
    188221        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
    189                      "No common name found in certificate for '%s:%d'. Looking for subject alternative name.",
     222                     "No common name found in certificate for '%s:%d'. Looking for subject alternative name...",
    190223                     s->server_hostname, s->port);
    191224        rv = 0;
     
    215248
    216249    return rv;
    217 
    218 }
     250}
     251
     252static int read_pgpcrt_cn(server_rec * s, apr_pool_t * p,
     253                       gnutls_openpgp_crt_t cert, char **cert_cn)
     254{
     255    int rv = 0;
     256    size_t data_len;
     257
     258
     259    *cert_cn = NULL;
     260
     261    data_len = 0;
     262    rv = gnutls_openpgp_crt_get_name(cert, 0, NULL, &data_len);
     263
     264    if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) {
     265        *cert_cn = apr_palloc(p, data_len);
     266        rv = gnutls_openpgp_crt_get_name(cert, 0, *cert_cn, &data_len);
     267    } else {                    /* No CN return subject alternative name */
     268        ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
     269                     "No name found in PGP certificate for '%s:%d'.",
     270                     s->server_hostname, s->port);
     271    }
     272
     273    return rv;
     274}
     275
    219276
    220277int
     
    351408            if (sc->enabled == GNUTLS_ENABLED_TRUE) {
    352409                rv = read_crt_cn(s, p, sc->certs_x509[0], &sc->cert_cn);
     410                if (rv < 0)  /* try openpgp certificate */
     411                    rv = read_pgpcrt_cn(s, p, sc->cert_pgp, &sc->cert_cn);
     412
    353413                if (rv < 0) {
    354414                    ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s,
     
    479539    ctxt = gnutls_transport_get_ptr(session);
    480540
    481     sni_type = gnutls_certificate_type_get(session);
    482     if (sni_type != GNUTLS_CRT_X509) {
    483         /* In theory, we could support OpenPGP Certificates. Theory != code. */
    484         ap_log_error(APLOG_MARK, APLOG_CRIT, 0,
    485                      ctxt->c->base_server,
    486                      "GnuTLS: Only x509 Certificates are currently supported.");
    487         return NULL;
    488     }
    489 
    490541    rv = gnutls_server_name_get(ctxt->session, sni_name,
    491542                                &data_len, &sni_type, 0);
     
    685736    apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp));
    686737
    687     mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0,
     738    if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509)
     739        mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0,
     740                             ctxt->sc->export_certificates_enabled);
     741    else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP)
     742        mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0,
    688743                             ctxt->sc->export_certificates_enabled);
    689744
     
    747802#define MGS_SIDE ((side==0)?"SSL_SERVER":"SSL_CLIENT")
    748803static void
    749 mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert, int side,
     804mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side,
    750805                         int export_certificates_enabled)
    751806{
     
    853908        }
    854909    }
    855 
    856 
    857 }
    858 
    859 
     910}
     911
     912static void
     913mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side,
     914                         int export_certificates_enabled)
     915{
     916    unsigned char sbuf[64];     /* buffer to hold serials */
     917    char buf[AP_IOBUFSIZE];
     918    const char *tmp;
     919    size_t len;
     920    int ret;
     921
     922    apr_table_t *env = r->subprocess_env;
     923
     924    if (export_certificates_enabled != 0) {
     925        char cert_buf[10 * 1024];
     926        len = sizeof(cert_buf);
     927
     928        if (gnutls_openpgp_crt_export
     929            (cert, GNUTLS_OPENPGP_FMT_BASE64, cert_buf, &len) >= 0)
     930            apr_table_setn(env,
     931                           apr_pstrcat(r->pool, MGS_SIDE, "_CERT", NULL),
     932                           apr_pstrmemdup(r->pool, cert_buf, len));
     933
     934    }
     935
     936    len = sizeof(buf);
     937    gnutls_openpgp_crt_get_name(cert, 0, buf, &len);
     938    apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_NAME", NULL),
     939                   apr_pstrmemdup(r->pool, buf, len));
     940
     941    len = sizeof(sbuf);
     942    gnutls_openpgp_crt_get_fingerprint(cert, sbuf, &len);
     943    tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf));
     944    apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_FINGERPRINT", NULL),
     945                   apr_pstrdup(r->pool, tmp));
     946
     947    ret = gnutls_openpgp_crt_get_version(cert);
     948    if (ret > 0)
     949        apr_table_setn(env,
     950                       apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", NULL),
     951                       apr_psprintf(r->pool, "%u", ret));
     952
     953    apr_table_setn(env,
     954       apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL), "OPENPGP");
     955
     956    tmp =
     957        mgs_time2sz(gnutls_openpgp_crt_get_expiration_time
     958                    (cert), buf, sizeof(buf));
     959    apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL),
     960                   apr_pstrdup(r->pool, tmp));
     961
     962    tmp =
     963        mgs_time2sz(gnutls_openpgp_crt_get_creation_time
     964                    (cert), buf, sizeof(buf));
     965    apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL),
     966                   apr_pstrdup(r->pool, tmp));
     967
     968    ret = gnutls_openpgp_crt_get_pk_algorithm(cert, NULL);
     969    if (ret >= 0) {
     970        apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", NULL),
     971                       gnutls_pk_algorithm_get_name(ret));
     972    }
     973
     974}
     975
     976/* FIXME: Allow client sending a certificate chain */
    860977static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt)
    861978{
     
    863980    unsigned int cert_list_size, status, expired;
    864981    int rv, ret;
    865     gnutls_x509_crt_t cert;
     982    union {
     983      gnutls_x509_crt_t x509;
     984      gnutls_openpgp_crt_t pgp;
     985    } cert;
    866986    apr_time_t activation_time, expiration_time, cur_time;
    867987
     
    8891009    }
    8901010
    891     gnutls_x509_crt_init(&cert);
    892     rv = gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER);
     1011    if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) {
     1012        gnutls_x509_crt_init(&cert.x509);
     1013        rv = gnutls_x509_crt_import(cert.x509, &cert_list[0], GNUTLS_X509_FMT_DER);
     1014    } else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) {
     1015        gnutls_openpgp_crt_init(&cert.pgp);
     1016        rv = gnutls_openpgp_crt_import(cert.pgp, &cert_list[0], GNUTLS_OPENPGP_FMT_RAW);
     1017    } else return HTTP_FORBIDDEN;
     1018 
    8931019    if (rv < 0) {
    894         ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
     1020       ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
    8951021                      "GnuTLS: Failed to Verify Peer: "
    8961022                      "Failed to import peer certificates.");
    897         ret = HTTP_FORBIDDEN;
    898         goto exit;
    899     }
    900 
    901     apr_time_ansi_put(&expiration_time,
    902                       gnutls_x509_crt_get_expiration_time(cert));
    903     apr_time_ansi_put(&activation_time,
    904                       gnutls_x509_crt_get_activation_time(cert));
    905 
    906     rv = gnutls_x509_crt_verify(cert, ctxt->sc->ca_list,
     1023       ret = HTTP_FORBIDDEN;
     1024       goto exit;
     1025    }
     1026
     1027    if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) {
     1028        apr_time_ansi_put(&expiration_time,
     1029                      gnutls_x509_crt_get_expiration_time(cert.x509));
     1030        apr_time_ansi_put(&activation_time,
     1031                      gnutls_x509_crt_get_activation_time(cert.x509));
     1032
     1033        rv = gnutls_x509_crt_verify(cert.x509, ctxt->sc->ca_list,
    9071034                                ctxt->sc->ca_list_size, 0, &status);
     1035    } else {
     1036        apr_time_ansi_put(&expiration_time,
     1037                      gnutls_openpgp_crt_get_expiration_time(cert.pgp));
     1038        apr_time_ansi_put(&activation_time,
     1039                      gnutls_openpgp_crt_get_creation_time(cert.pgp));
     1040
     1041        rv = gnutls_openpgp_crt_verify_ring(cert.pgp, ctxt->sc->pgp_list,
     1042                      0, &status);
     1043    }
     1044
    9081045
    9091046    if (rv < 0) {
     
    9581095//    rv = mgs_authz_lua(r);
    9591096
    960     mgs_add_common_cert_vars(r, cert, 1,
     1097    if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509)
     1098        mgs_add_common_cert_vars(r, cert.x509, 1,
     1099                             ctxt->sc->export_certificates_enabled);
     1100    else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP)
     1101        mgs_add_common_pgpcert_vars(r, cert.pgp, 1,
    9611102                             ctxt->sc->export_certificates_enabled);
    9621103
     
    9821123
    9831124  exit:
    984     gnutls_x509_crt_deinit(cert);
     1125    if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509)
     1126        gnutls_x509_crt_deinit(cert.x509);
     1127    else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP)
     1128        gnutls_openpgp_crt_deinit(cert.pgp);
    9851129    return ret;
    9861130
  • src/mod_gnutls.c

    rd2439b9 re5bbda4  
    6565                  RSRC_CONF,
    6666                  "Set the CA File to verify Client Certificates"),
     67    AP_INIT_TAKE1("GnuTLSPGPKeyringFile", mgs_set_keyring_file,
     68                  NULL,
     69                  RSRC_CONF,
     70                  "Set the Keyring File to verify Client Certificates"),
    6771    AP_INIT_TAKE1("GnuTLSDHFile", mgs_set_dh_file,
    6872                  NULL,
     
    7680                  NULL,
    7781                  RSRC_CONF,
    78                   "SSL Server Key file"),
     82                  "SSL Server Certificate file"),
    7983    AP_INIT_TAKE1("GnuTLSKeyFile", mgs_set_key_file,
    8084                  NULL,
    8185                  RSRC_CONF,
    82                   "SSL Server SRP Password file"),
     86                  "SSL Server Private Key file"),
     87    AP_INIT_TAKE1("GnuTLSPGPCertificateFile", mgs_set_pgpcert_file,
     88                  NULL,
     89                  RSRC_CONF,
     90                  "SSL Server PGP Certificate file"),
     91    AP_INIT_TAKE1("GnuTLSPGPKeyFile", mgs_set_pgpkey_file,
     92                  NULL,
     93                  RSRC_CONF,
     94                  "SSL Server PGP Private key file"),
    8395    AP_INIT_TAKE1("GnuTLSSRPPasswdFile", mgs_set_srp_tpasswd_file,
    8496                  NULL,
Note: See TracChangeset for help on using the changeset viewer.