libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 26766bf6f7a161b7df8170d5e8f1a088da13f12c
parent 3b9bb09488b3d5d03a9517c810539f5b9e985d96
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun, 16 Nov 2008 04:47:42 +0000

more DCE

Diffstat:
Msrc/daemon/https/gnutls.h | 6------
Msrc/daemon/https/tls/gnutls_cert.c | 86-------------------------------------------------------------------------------
Msrc/daemon/https/tls/gnutls_x509.c | 110-------------------------------------------------------------------------------
Msrc/daemon/https/x509/Makefile.am | 1-
Msrc/daemon/https/x509/common.c | 198+------------------------------------------------------------------------------
Msrc/daemon/https/x509/common.h | 16----------------
Dsrc/daemon/https/x509/verify.h | 33---------------------------------
Msrc/daemon/https/x509/x509.c | 1-
Msrc/daemon/https/x509/x509.h | 9---------
Msrc/daemon/https/x509/x509_privkey.c | 1-
Dsrc/daemon/https/x509/x509_verify.c | 715-------------------------------------------------------------------------------
11 files changed, 2 insertions(+), 1174 deletions(-)

diff --git a/src/daemon/https/gnutls.h b/src/daemon/https/gnutls.h @@ -700,12 +700,6 @@ extern "C" time_t MHD_gtls_certificate_expiration_time_peers (MHD_gtls_session_t session); - int MHD_gtls_certificate_verify_peers2 (MHD_gtls_session_t session, - unsigned int *status); - - /* this is obsolete (?). */ - int MHD_gtls_certificate_verify_peers (MHD_gtls_session_t session); - int MHD_gtls_pem_base64_encode (const char *msg, const MHD_gnutls_datum_t * data, char *result, size_t * result_size); diff --git a/src/daemon/https/tls/gnutls_cert.c b/src/daemon/https/tls/gnutls_cert.c @@ -430,92 +430,6 @@ MHD__gnutls_x509_get_raw_crt_expiration_time (const MHD_gnutls_datum_t * cert) } /** - * MHD_gtls_certificate_verify_peers2 - This function returns the peer's certificate verification status - * @session: is a gnutls session - * @status: is the output of the verification - * - * This function will try to verify the peer's certificate and return - * its status (trusted, invalid etc.). The value of @status should - * be one or more of the MHD_gnutls_certificate_status_t enumerated - * elements bitwise or'd. To avoid denial of service attacks some - * default upper limits regarding the certificate key size and chain - * size are set. To override them use - * MHD__gnutls_certificate_set_verify_limits(). - * - * Note that you must also check the peer's name in order to check if - * the verified certificate belongs to the actual peer. - * - * This is the same as MHD_gnutls_x509_crt_list_verify() and uses the - * loaded CAs in the credentials as trusted CAs. - * - * Note that some commonly used X.509 Certificate Authorities are - * still using Version 1 certificates. If you want to accept them, - * you need to call MHD__gnutls_certificate_set_verify_flags() with, e.g., - * %GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT parameter. - * - * Returns: a negative error code on error and zero on success. - **/ -int -MHD_gtls_certificate_verify_peers2 (MHD_gtls_session_t session, - unsigned int *status) -{ - cert_auth_info_t info; - - CHECK_AUTH (MHD_GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST); - - info = MHD_gtls_get_auth_info (session); - if (info == NULL) - { - return GNUTLS_E_NO_CERTIFICATE_FOUND; - } - - if (info->raw_certificate_list == NULL || info->ncerts == 0) - return GNUTLS_E_NO_CERTIFICATE_FOUND; - - switch (MHD_gnutls_certificate_type_get (session)) - { - case MHD_GNUTLS_CRT_X509: - return MHD__gnutls_x509_cert_verify_peers (session, status); - default: - return GNUTLS_E_INVALID_REQUEST; - } -} - -/** - * MHD_gtls_certificate_verify_peers - This function returns the peer's certificate verification status - * @session: is a gnutls session - * - * This function will try to verify the peer's certificate and return - * its status (trusted, invalid etc.). However you must also check - * the peer's name in order to check if the verified certificate - * belongs to the actual peer. - * - * The return value should be one or more of the - * MHD_gnutls_certificate_status_t enumerated elements bitwise or'd, or a - * negative value on error. - * - * This is the same as MHD_gnutls_x509_crt_list_verify(). - * - * Deprecated: Use MHD_gtls_certificate_verify_peers2() instead. - **/ -int -MHD_gtls_certificate_verify_peers (MHD_gtls_session_t session) -{ - unsigned int status; - int ret; - - ret = MHD_gtls_certificate_verify_peers2 (session, &status); - - if (ret < 0) - { - MHD_gnutls_assert (); - return ret; - } - - return status; -} - -/** * MHD_gtls_certificate_expiration_time_peers - This function returns the peer's certificate expiration time * @session: is a gnutls session * diff --git a/src/daemon/https/tls/gnutls_x509.c b/src/daemon/https/tls/gnutls_x509.c @@ -48,7 +48,6 @@ /* x509 */ #include "common.h" #include "x509.h" -#include "verify.h" #include "mpi.h" #include "privkey.h" @@ -89,115 +88,6 @@ check_bits (MHD_gnutls_x509_crt_t crt, unsigned int max_bits) } \ MHD_gnutls_free( peer_certificate_list) -/*- - * MHD__gnutls_x509_cert_verify_peers - This function returns the peer's certificate status - * @session: is a gnutls session - * - * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.). - * The return value (status) should be one of the MHD_gnutls_certificate_status_t enumerated elements. - * However you must also check the peer's name in order to check if the verified certificate belongs to the - * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent. - * - -*/ -int -MHD__gnutls_x509_cert_verify_peers (MHD_gtls_session_t session, - unsigned int *status) -{ - cert_auth_info_t info; - MHD_gtls_cert_credentials_t cred; - MHD_gnutls_x509_crt_t *peer_certificate_list; - int peer_certificate_list_size, i, x, ret; - - CHECK_AUTH (MHD_GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST); - - info = MHD_gtls_get_auth_info (session); - if (info == NULL) - { - MHD_gnutls_assert (); - return GNUTLS_E_INVALID_REQUEST; - } - - cred = (MHD_gtls_cert_credentials_t) - MHD_gtls_get_cred (session->key, MHD_GNUTLS_CRD_CERTIFICATE, NULL); - if (cred == NULL) - { - MHD_gnutls_assert (); - return GNUTLS_E_INSUFFICIENT_CREDENTIALS; - } - - if (info->raw_certificate_list == NULL || info->ncerts == 0) - return GNUTLS_E_NO_CERTIFICATE_FOUND; - - if (info->ncerts > cred->verify_depth && cred->verify_depth > 0) - { - MHD_gnutls_assert (); - return GNUTLS_E_CONSTRAINT_ERROR; - } - - /* generate a list of MHD_gnutls_certs based on the auth info - * raw certs. - */ - peer_certificate_list_size = info->ncerts; - peer_certificate_list = - MHD_gnutls_calloc (peer_certificate_list_size, - sizeof (MHD_gnutls_x509_crt_t)); - if (peer_certificate_list == NULL) - { - MHD_gnutls_assert (); - return GNUTLS_E_MEMORY_ERROR; - } - - for (i = 0; i < peer_certificate_list_size; i++) - { - ret = MHD_gnutls_x509_crt_init (&peer_certificate_list[i]); - if (ret < 0) - { - MHD_gnutls_assert (); - CLEAR_CERTS; - return ret; - } - - ret = - MHD_gnutls_x509_crt_import (peer_certificate_list[i], - &info->raw_certificate_list[i], - GNUTLS_X509_FMT_DER); - if (ret < 0) - { - MHD_gnutls_assert (); - CLEAR_CERTS; - return ret; - } - - ret = check_bits (peer_certificate_list[i], cred->verify_bits); - if (ret < 0) - { - MHD_gnutls_assert (); - CLEAR_CERTS; - return ret; - } - - } - - /* Verify certificate - */ - ret = - MHD_gnutls_x509_crt_list_verify (peer_certificate_list, - peer_certificate_list_size, - cred->x509_ca_list, cred->x509_ncas, - cred->x509_crl_list, cred->x509_ncrls, - cred->verify_flags, status); - - CLEAR_CERTS; - - if (ret < 0) - { - MHD_gnutls_assert (); - return ret; - } - - return 0; -} - /* * Read certificates and private keys, from memory etc. */ diff --git a/src/daemon/https/x509/Makefile.am b/src/daemon/https/x509/Makefile.am @@ -23,6 +23,5 @@ extensions.c extensions.h \ mpi.c mpi.h \ pkcs12.h \ x509_privkey.c privkey.h \ -x509_verify.c verify.h \ x509.c x509.h diff --git a/src/daemon/https/x509/common.c b/src/daemon/https/x509/common.c @@ -218,7 +218,7 @@ MHD_gnutls_x509_dn_oid_known (const char *oid) /* Returns 1 if the data defined by the OID are of a choice * type. */ -int +static int MHD__gnutls_x509_oid_data_choice (const char *oid) { int i = 0; @@ -815,7 +815,7 @@ MHD__gnutls_x509_export_int (ASN1_TYPE MHD__asn1_data, * octet string. Otherwise put something like BMPString, PrintableString * etc. */ -int +static int MHD__gnutls_x509_decode_octet_string (const char *string_type, const opaque * der, size_t der_size, @@ -1029,200 +1029,6 @@ cleanup:MHD_gnutls_free (data); } -/* DER Encodes the src ASN1_TYPE and stores it to - * dest in dest_name. Useful to encode something and store it - * as OCTET. If str is non null then the data are encoded as - * an OCTET STRING. - */ -int -MHD__gnutls_x509_der_encode_and_copy (ASN1_TYPE src, - const char *src_name, - ASN1_TYPE dest, - const char *dest_name, int str) -{ - int result; - MHD_gnutls_datum_t encoded; - - result = MHD__gnutls_x509_der_encode (src, src_name, &encoded, str); - - if (result < 0) - { - MHD_gnutls_assert (); - return result; - } - - /* Write the data. - */ - result = - MHD__asn1_write_value (dest, dest_name, encoded.data, encoded.size); - - MHD__gnutls_free_datum (&encoded); - - if (result != ASN1_SUCCESS) - { - MHD_gnutls_assert (); - return MHD_gtls_asn2err (result); - } - - return 0; -} - -/* Writes the value of the datum in the given ASN1_TYPE. If str is non - * zero it encodes it as OCTET STRING. - */ -int -MHD__gnutls_x509_write_value (ASN1_TYPE c, - const char *root, - const MHD_gnutls_datum_t * data, int str) -{ - int result; - int asize; - ASN1_TYPE c2 = ASN1_TYPE_EMPTY; - MHD_gnutls_datum_t val; - - asize = data->size + 16; - - val.data = MHD_gnutls_malloc (asize); - if (val.data == NULL) - { - MHD_gnutls_assert (); - result = GNUTLS_E_MEMORY_ERROR; - goto cleanup; - } - - if (str) - { - /* Convert it to OCTET STRING - */ - if ((result = - MHD__asn1_create_element (MHD__gnutls_get_pkix (), - "PKIX1.pkcs-7-Data", - &c2)) != ASN1_SUCCESS) - { - MHD_gnutls_assert (); - result = MHD_gtls_asn2err (result); - goto cleanup; - } - - result = MHD__asn1_write_value (c2, "", data->data, data->size); - if (result != ASN1_SUCCESS) - { - MHD_gnutls_assert (); - result = MHD_gtls_asn2err (result); - goto cleanup; - } - - result = MHD__gnutls_x509_der_encode (c2, "", &val, 0); - if (result < 0) - { - MHD_gnutls_assert (); - goto cleanup; - } - - } - else - { - val.data = data->data; - val.size = data->size; - } - - /* Write the data. - */ - result = MHD__asn1_write_value (c, root, val.data, val.size); - - if (val.data != data->data) - MHD__gnutls_free_datum (&val); - - if (result != ASN1_SUCCESS) - { - MHD_gnutls_assert (); - return MHD_gtls_asn2err (result); - } - - return 0; - -cleanup:if (val.data != data->data) - MHD__gnutls_free_datum (&val); - return result; -} - -/* Encodes and copies the private key parameters into a - * subjectPublicKeyInfo structure. - * - */ -int -MHD__gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst, - const char *dst_name, - enum - MHD_GNUTLS_PublicKeyAlgorithm - pk_algorithm, mpi_t * params, - int params_size) -{ - const char *pk; - MHD_gnutls_datum_t der = { NULL, - 0 - }; - int result; - char name[128]; - - pk = MHD_gtls_x509_pk_to_oid (pk_algorithm); - if (pk == NULL) - { - MHD_gnutls_assert (); - return GNUTLS_E_UNKNOWN_PK_ALGORITHM; - } - - /* write the OID - */ - MHD_gtls_str_cpy (name, sizeof (name), dst_name); - MHD_gtls_str_cat (name, sizeof (name), ".algorithm.algorithm"); - result = MHD__asn1_write_value (dst, name, pk, 1); - if (result != ASN1_SUCCESS) - { - MHD_gnutls_assert (); - return MHD_gtls_asn2err (result); - } - - if (pk_algorithm == MHD_GNUTLS_PK_RSA) - { - /* disable parameters, which are not used in RSA. - */ - MHD_gtls_str_cpy (name, sizeof (name), dst_name); - MHD_gtls_str_cat (name, sizeof (name), ".algorithm.parameters"); - result = MHD__asn1_write_value (dst, name, NULL, 0); - if (result != ASN1_SUCCESS) - { - MHD_gnutls_assert (); - return MHD_gtls_asn2err (result); - } - - result = MHD__gnutls_x509_write_rsa_params (params, params_size, &der); - if (result < 0) - { - MHD_gnutls_assert (); - return result; - } - - /* Write the DER parameters. (in bits) - */ - MHD_gtls_str_cpy (name, sizeof (name), dst_name); - MHD_gtls_str_cat (name, sizeof (name), ".subjectPublicKey"); - result = MHD__asn1_write_value (dst, name, der.data, der.size * 8); - - MHD__gnutls_free_datum (&der); - - if (result != ASN1_SUCCESS) - { - MHD_gnutls_assert (); - return MHD_gtls_asn2err (result); - } - } - else - return GNUTLS_E_UNIMPLEMENTED_FEATURE; - - return 0; -} - /* Reads and returns the PK algorithm of the given certificate-like * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo". */ diff --git a/src/daemon/https/x509/common.h b/src/daemon/https/x509/common.h @@ -58,10 +58,6 @@ #define SIG_GOST_R3410_94_OID "1.2.643.2.2.4" #define SIG_GOST_R3410_2001_OID "1.2.643.2.2.3" -int MHD__gnutls_x509_decode_octet_string (const char *string_type, - const opaque * der, size_t der_size, - opaque * output, - size_t * output_size); int MHD__gnutls_x509_oid_data2string (const char *OID, void *value, int value_size, char *res, size_t * res_size); @@ -70,7 +66,6 @@ int MHD__gnutls_x509_data2hex (const opaque * data, size_t data_size, const char *MHD__gnutls_x509_oid2ldap_string (const char *OID); -int MHD__gnutls_x509_oid_data_choice (const char *OID); int MHD__gnutls_x509_oid_data_printable (const char *OID); time_t MHD__gnutls_x509_get_time (ASN1_TYPE c2, const char *when); @@ -78,9 +73,6 @@ time_t MHD__gnutls_x509_get_time (ASN1_TYPE c2, const char *when); MHD_gnutls_x509_subject_alt_name_t MHD__gnutls_x509_san_find_type (char *str_type); -int MHD__gnutls_x509_der_encode_and_copy (ASN1_TYPE src, const char *src_name, - ASN1_TYPE dest, - const char *dest_name, int str); int MHD__gnutls_x509_der_encode (ASN1_TYPE src, const char *src_name, MHD_gnutls_datum_t * res, int str); @@ -91,8 +83,6 @@ int MHD__gnutls_x509_export_int (ASN1_TYPE MHD__asn1_data, int MHD__gnutls_x509_read_value (ASN1_TYPE c, const char *root, MHD_gnutls_datum_t * ret, int str); -int MHD__gnutls_x509_write_value (ASN1_TYPE c, const char *root, - const MHD_gnutls_datum_t * data, int str); int MHD__gnutls_x509_decode_and_read_attribute (ASN1_TYPE MHD__asn1_struct, const char *where, char *oid, @@ -103,12 +93,6 @@ int MHD__gnutls_x509_decode_and_read_attribute (ASN1_TYPE MHD__asn1_struct, int MHD__gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name, unsigned int *bits); -int MHD__gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst, - const char *dst_name, - enum - MHD_GNUTLS_PublicKeyAlgorithm - pk_algorithm, mpi_t * params, - int params_size); int MHD__gnutls_asn1_copy_node (ASN1_TYPE * dst, const char *dst_name, ASN1_TYPE src, const char *src_name); diff --git a/src/daemon/https/x509/verify.h b/src/daemon/https/x509/verify.h @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005 Free Software Foundation - * - * Author: Nikos Mavrogiannopoulos - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA - * - */ - -#include "x509.h" - -int MHD_gnutls_x509_crt_is_issuer (MHD_gnutls_x509_crt_t cert, - MHD_gnutls_x509_crt_t issuer); -int MHD__gnutls_x509_privkey_verify_signature (const MHD_gnutls_datum_t * tbs, - const MHD_gnutls_datum_t * - signature, - MHD_gnutls_x509_privkey_t - issuer); diff --git a/src/daemon/https/x509/x509.c b/src/daemon/https/x509/x509.c @@ -37,7 +37,6 @@ #include <libtasn1.h> #include <mpi.h> #include <privkey.h> -#include <verify.h> /** * MHD_gnutls_x509_crt_init - This function initializes a MHD_gnutls_x509_crt_t structure diff --git a/src/daemon/https/x509/x509.h b/src/daemon/https/x509/x509.h @@ -300,15 +300,6 @@ extern "C" GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5 = 32 } MHD_gnutls_certificate_verify_flags; - int MHD_gnutls_x509_crt_list_verify (const MHD_gnutls_x509_crt_t * - cert_list, int cert_list_length, - const MHD_gnutls_x509_crt_t * CA_list, - int CA_list_length, - const MHD_gnutls_x509_crl_t * CRL_list, - int CRL_list_length, - unsigned int flags, - unsigned int *verify); - int MHD_gnutls_x509_crt_check_revocation (MHD_gnutls_x509_crt_t cert, const MHD_gnutls_x509_crl_t * crl_list, int crl_list_length); diff --git a/src/daemon/https/x509/x509_privkey.c b/src/daemon/https/x509/x509_privkey.c @@ -35,7 +35,6 @@ #include <dn.h> #include <mpi.h> #include <extensions.h> -#include <verify.h> static int MHD__gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params); int MHD__gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params); diff --git a/src/daemon/https/x509/x509_verify.c b/src/daemon/https/x509/x509_verify.c @@ -1,715 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation - * - * Author: Nikos Mavrogiannopoulos - * - * This file is part of GNUTLS. - * - * The GNUTLS library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public License - * as published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA - * - */ - -/* All functions which relate to X.509 certificate verification stuff are - * included here - */ - -#include <gnutls_int.h> -#include <gnutls_errors.h> -#include <gnutls_cert.h> -#include <libtasn1.h> -#include <gnutls_global.h> -#include <gnutls_num.h> /* MAX */ -#include <gnutls_sig.h> -#include <gnutls_str.h> -#include <gnutls_datum.h> -#include <dn.h> -#include <x509.h> -#include <mpi.h> -#include <common.h> -#include <verify.h> - -static int MHD__gnutls_verify_certificate2 (MHD_gnutls_x509_crt_t cert, - const MHD_gnutls_x509_crt_t * - trusted_cas, int tcas_size, - unsigned int flags, - unsigned int *output); -static int MHD__gnutls_x509_verify_signature (const MHD_gnutls_datum_t * signed_data, - const MHD_gnutls_datum_t * signature, - MHD_gnutls_x509_crt_t issuer); - -/* Checks if the issuer of a certificate is a - * Certificate Authority, or if the certificate is the same - * as the issuer (and therefore it doesn't need to be a CA). - * - * Returns true or false, if the issuer is a CA, - * or not. - */ -static int -check_if_ca (MHD_gnutls_x509_crt_t cert, - MHD_gnutls_x509_crt_t issuer, unsigned int flags) -{ - MHD_gnutls_datum_t cert_signed_data = { NULL, - 0 - }; - MHD_gnutls_datum_t issuer_signed_data = { NULL, - 0 - }; - MHD_gnutls_datum_t cert_signature = { NULL, - 0 - }; - MHD_gnutls_datum_t issuer_signature = { NULL, - 0 - }; - int result; - - /* Check if the issuer is the same with the - * certificate. This is added in order for trusted - * certificates to be able to verify themselves. - */ - - result = MHD__gnutls_x509_get_signed_data (issuer->cert, "tbsCertificate", - &issuer_signed_data); - if (result < 0) - { - MHD_gnutls_assert (); - goto cleanup; - } - - result = MHD__gnutls_x509_get_signed_data (cert->cert, "tbsCertificate", - &cert_signed_data); - if (result < 0) - { - MHD_gnutls_assert (); - goto cleanup; - } - - result = MHD__gnutls_x509_get_signature (issuer->cert, "signature", - &issuer_signature); - if (result < 0) - { - MHD_gnutls_assert (); - goto cleanup; - } - - result = - MHD__gnutls_x509_get_signature (cert->cert, "signature", &cert_signature); - if (result < 0) - { - MHD_gnutls_assert (); - goto cleanup; - } - - /* If the subject certificate is the same as the issuer - * return true. - */ - if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME)) - if (cert_signed_data.size == issuer_signed_data.size) - { - if ((memcmp (cert_signed_data.data, issuer_signed_data.data, - cert_signed_data.size) == 0) && (cert_signature.size - == - issuer_signature.size) - && - (memcmp - (cert_signature.data, issuer_signature.data, - cert_signature.size) == 0)) - { - result = 1; - goto cleanup; - } - } - - if (MHD_gnutls_x509_crt_get_ca_status (issuer, NULL) == 1) - { - result = 1; - goto cleanup; - } - else - MHD_gnutls_assert (); - - result = 0; - -cleanup:MHD__gnutls_free_datum (&cert_signed_data); - MHD__gnutls_free_datum (&issuer_signed_data); - MHD__gnutls_free_datum (&cert_signature); - MHD__gnutls_free_datum (&issuer_signature); - return result; -} - -/* This function checks if 'certs' issuer is 'issuer_cert'. - * This does a straight (DER) compare of the issuer/subject fields in - * the given certificates. - * - * Returns 1 if they match and zero if they don't match. Otherwise - * a negative value is returned to indicate error. - */ -static int -is_issuer (MHD_gnutls_x509_crt_t cert, MHD_gnutls_x509_crt_t issuer_cert) -{ - MHD_gnutls_datum_t dn1 = { NULL, - 0 - }, dn2 = - { - NULL, 0}; - int ret; - - ret = MHD_gnutls_x509_crt_get_raw_issuer_dn (cert, &dn1); - if (ret < 0) - { - MHD_gnutls_assert (); - goto cleanup; - } - - ret = MHD_gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2); - if (ret < 0) - { - MHD_gnutls_assert (); - goto cleanup; - } - - ret = MHD__gnutls_x509_compare_raw_dn (&dn1, &dn2); - -cleanup:MHD__gnutls_free_datum (&dn1); - MHD__gnutls_free_datum (&dn2); - return ret; - -} - -static inline MHD_gnutls_x509_crt_t -find_issuer (MHD_gnutls_x509_crt_t cert, - const MHD_gnutls_x509_crt_t * trusted_cas, int tcas_size) -{ - int i; - - /* this is serial search. - */ - - for (i = 0; i < tcas_size; i++) - { - if (is_issuer (cert, trusted_cas[i]) == 1) - return trusted_cas[i]; - } - - MHD_gnutls_assert (); - return NULL; -} - -/* - * Verifies the given certificate again a certificate list of - * trusted CAs. - * - * Returns only 0 or 1. If 1 it means that the certificate - * was successfuly verified. - * - * 'flags': an OR of the MHD_gnutls_certificate_verify_flags enumeration. - * - * Output will hold some extra information about the verification - * procedure. - */ -static int -MHD__gnutls_verify_certificate2 (MHD_gnutls_x509_crt_t cert, - const MHD_gnutls_x509_crt_t * trusted_cas, - int tcas_size, - unsigned int flags, unsigned int *output) -{ - MHD_gnutls_datum_t cert_signed_data = { NULL, - 0 - }; - MHD_gnutls_datum_t cert_signature = { NULL, - 0 - }; - MHD_gnutls_x509_crt_t issuer; - int ret, issuer_version, result; - - if (output) - *output = 0; - - if (tcas_size >= 1) - issuer = find_issuer (cert, trusted_cas, tcas_size); - else - { - MHD_gnutls_assert (); - if (output) - *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID; - return 0; - } - - /* issuer is not in trusted certificate - * authorities. - */ - if (issuer == NULL) - { - if (output) - *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID; - MHD_gnutls_assert (); - return 0; - } - - issuer_version = MHD_gnutls_x509_crt_get_version (issuer); - if (issuer_version < 0) - { - MHD_gnutls_assert (); - return issuer_version; - } - - if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) && !((flags - & - GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT) - && issuer_version == 1)) - { - if (check_if_ca (cert, issuer, flags) == 0) - { - MHD_gnutls_assert (); - if (output) - *output |= GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID; - return 0; - } - } - - result = MHD__gnutls_x509_get_signed_data (cert->cert, "tbsCertificate", - &cert_signed_data); - if (result < 0) - { - MHD_gnutls_assert (); - goto cleanup; - } - - result = - MHD__gnutls_x509_get_signature (cert->cert, "signature", &cert_signature); - if (result < 0) - { - MHD_gnutls_assert (); - goto cleanup; - } - - ret = MHD__gnutls_x509_verify_signature (&cert_signed_data, &cert_signature, - issuer); - if (ret < 0) - { - MHD_gnutls_assert (); - } - else if (ret == 0) - { - MHD_gnutls_assert (); - /* error. ignore it */ - if (output) - *output |= GNUTLS_CERT_INVALID; - ret = 0; - } - - /* If the certificate is not self signed check if the algorithms - * used are secure. If the certificate is self signed it doesn't - * really matter. - */ - if (is_issuer (cert, cert) == 0) - { - int sigalg; - - sigalg = MHD_gnutls_x509_crt_get_signature_algorithm (cert); - - if (((sigalg == GNUTLS_SIGN_RSA_MD2) && !(flags - & - GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) - || ((sigalg == GNUTLS_SIGN_RSA_MD5) - && !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5))) - { - if (output) - *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID; - } - } - - result = ret; - -cleanup:MHD__gnutls_free_datum (&cert_signed_data); - MHD__gnutls_free_datum (&cert_signature); - - return result; -} - -/** - * MHD_gnutls_x509_crt_check_issuer - This function checks if the certificate given has the given issuer - * @cert: is the certificate to be checked - * @issuer: is the certificate of a possible issuer - * - * This function will check if the given certificate was issued by the - * given issuer. It will return true (1) if the given certificate is issued - * by the given issuer, and false (0) if not. - * - * A negative value is returned in case of an error. - * - **/ -static int -MHD_gnutls_x509_crt_check_issuer (MHD_gnutls_x509_crt_t cert, - MHD_gnutls_x509_crt_t issuer) -{ - return is_issuer (cert, issuer); -} - -/* The algorithm used is: - * 1. Check last certificate in the chain. If it is not verified return. - * 2. Check if any certificates in the chain are revoked. If yes return. - * 3. Try to verify the rest of certificates in the chain. If not verified return. - * 4. Return 0. - * - * Note that the return value is an OR of GNUTLS_CERT_* elements. - * - * This function verifies a X.509 certificate list. The certificate list should - * lead to a trusted CA in order to be trusted. - */ -static unsigned int -MHD__gnutls_x509_verify_certificate (const MHD_gnutls_x509_crt_t * - certificate_list, int clist_size, - const MHD_gnutls_x509_crt_t * - trusted_cas, int tcas_size, - const MHD_gnutls_x509_crl_t * CRLs, - int crls_size, unsigned int flags) -{ - int i = 0, ret; - unsigned int status = 0, output; - - /* Verify the last certificate in the certificate path - * against the trusted CA certificate list. - * - * If no CAs are present returns CERT_INVALID. Thus works - * in self signed etc certificates. - */ - ret = MHD__gnutls_verify_certificate2 (certificate_list[clist_size - 1], - trusted_cas, tcas_size, flags, - &output); - - if (ret == 0) - { - /* if the last certificate in the certificate - * list is invalid, then the certificate is not - * trusted. - */ - MHD_gnutls_assert (); - status |= output; - status |= GNUTLS_CERT_INVALID; - return status; - } - - /* Check if the last certificate in the path is self signed. - * In that case ignore it (a certificate is trusted only if it - * leads to a trusted party by us, not the server's). - */ - if (MHD_gnutls_x509_crt_check_issuer (certificate_list[clist_size - 1], - certificate_list[clist_size - 1]) > 0 - && clist_size > 0) - { - clist_size--; - } - - /* Verify the certificate path (chain) - */ - for (i = clist_size - 1; i > 0; i--) - { - if (i - 1 < 0) - break; - - /* note that here we disable this V1 CA flag. So that no version 1 - * certificates can exist in a supplied chain. - */ - if (!(flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT)) - flags ^= GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT; - if ((ret = MHD__gnutls_verify_certificate2 (certificate_list[i - 1], - &certificate_list[i], 1, - flags, NULL)) == 0) - { - status |= GNUTLS_CERT_INVALID; - return status; - } - } - - return 0; -} - -/* Reads the digest information. - * we use DER here, although we should use BER. It works fine - * anyway. - */ -static int -decode_ber_digest_info (const MHD_gnutls_datum_t * info, - enum MHD_GNUTLS_HashAlgorithm *hash, - opaque * digest, int *digest_size) -{ - ASN1_TYPE dinfo = ASN1_TYPE_EMPTY; - int result; - char str[1024]; - int len; - - if ((result = MHD__asn1_create_element (MHD__gnutls_getMHD__gnutls_asn (), - "GNUTLS.DigestInfo", - &dinfo)) != ASN1_SUCCESS) - { - MHD_gnutls_assert (); - return MHD_gtls_asn2err (result); - } - - result = MHD__asn1_der_decoding (&dinfo, info->data, info->size, NULL); - if (result != ASN1_SUCCESS) - { - MHD_gnutls_assert (); - MHD__asn1_delete_structure (&dinfo); - return MHD_gtls_asn2err (result); - } - - len = sizeof (str) - 1; - result = - MHD__asn1_read_value (dinfo, "digestAlgorithm.algorithm", str, &len); - if (result != ASN1_SUCCESS) - { - MHD_gnutls_assert (); - MHD__asn1_delete_structure (&dinfo); - return MHD_gtls_asn2err (result); - } - - *hash = MHD_gtls_x509_oid2mac_algorithm (str); - - if (*hash == MHD_GNUTLS_MAC_UNKNOWN) - { - - MHD__gnutls_x509_log ("verify.c: HASH OID: %s\n", str); - - MHD_gnutls_assert (); - MHD__asn1_delete_structure (&dinfo); - return GNUTLS_E_UNKNOWN_ALGORITHM; - } - - len = sizeof (str) - 1; - result = - MHD__asn1_read_value (dinfo, "digestAlgorithm.parameters", str, &len); - /* To avoid permitting garbage in the parameters field, either the - parameters field is not present, or it contains 0x05 0x00. */ - if (! - (result == ASN1_ELEMENT_NOT_FOUND - || (result == ASN1_SUCCESS && len == 2 && str[0] == 0x05 - && str[1] == 0x00))) - { - MHD_gnutls_assert (); - MHD__asn1_delete_structure (&dinfo); - return GNUTLS_E_ASN1_GENERIC_ERROR; - } - - result = MHD__asn1_read_value (dinfo, "digest", digest, digest_size); - if (result != ASN1_SUCCESS) - { - MHD_gnutls_assert (); - MHD__asn1_delete_structure (&dinfo); - return MHD_gtls_asn2err (result); - } - - MHD__asn1_delete_structure (&dinfo); - - return 0; -} - -/* if hash==MD5 then we do RSA-MD5 - * if hash==SHA then we do RSA-SHA - * params[0] is modulus - * params[1] is public key - */ -static int -_pkcs1_rsa_verify_sig (const MHD_gnutls_datum_t * text, - const MHD_gnutls_datum_t * signature, - mpi_t * params, int params_len) -{ - enum MHD_GNUTLS_HashAlgorithm hash = MHD_GNUTLS_MAC_UNKNOWN; - int ret; - opaque digest[MAX_HASH_SIZE], md[MAX_HASH_SIZE]; - int digest_size; - GNUTLS_HASH_HANDLE hd; - MHD_gnutls_datum_t decrypted; - - ret = - MHD_gtls_pkcs1_rsa_decrypt (&decrypted, signature, params, params_len, 1); - if (ret < 0) - { - MHD_gnutls_assert (); - return ret; - } - - /* decrypted is a BER encoded data of type DigestInfo - */ - - digest_size = sizeof (digest); - if ((ret = decode_ber_digest_info (&decrypted, &hash, digest, &digest_size)) - != 0) - { - MHD_gnutls_assert (); - MHD__gnutls_free_datum (&decrypted); - return ret; - } - - MHD__gnutls_free_datum (&decrypted); - - if (digest_size != MHD_gnutls_hash_get_algo_len (hash)) - { - MHD_gnutls_assert (); - return GNUTLS_E_ASN1_GENERIC_ERROR; - } - - hd = MHD_gtls_hash_init (hash); - if (hd == NULL) - { - MHD_gnutls_assert (); - return GNUTLS_E_HASH_FAILED; - } - - MHD_gnutls_hash (hd, text->data, text->size); - MHD_gnutls_hash_deinit (hd, md); - - if (memcmp (md, digest, digest_size) != 0) - { - MHD_gnutls_assert (); - return GNUTLS_E_PK_SIG_VERIFY_FAILED; - } - - return 0; -} - -/* Verifies the signature data, and returns 0 if not verified, - * or 1 otherwise. - */ -static int -verify_sig (const MHD_gnutls_datum_t * tbs, - const MHD_gnutls_datum_t * signature, - enum MHD_GNUTLS_PublicKeyAlgorithm pk, - mpi_t * issuer_params, int issuer_params_size) -{ - - switch (pk) - { - case MHD_GNUTLS_PK_RSA: - - if (_pkcs1_rsa_verify_sig - (tbs, signature, issuer_params, issuer_params_size) != 0) - { - MHD_gnutls_assert (); - return 0; - } - - return 1; - break; - - default: - MHD_gnutls_assert (); - return GNUTLS_E_INTERNAL_ERROR; - - } -} - -/* verifies if the certificate is properly signed. - * returns 0 on failure and 1 on success. - * - * 'tbs' is the signed data - * 'signature' is the signature! - */ -static int -MHD__gnutls_x509_verify_signature (const MHD_gnutls_datum_t * tbs, - const MHD_gnutls_datum_t * signature, - MHD_gnutls_x509_crt_t issuer) -{ - mpi_t issuer_params[MAX_PUBLIC_PARAMS_SIZE]; - int ret, issuer_params_size, i; - - /* Read the MPI parameters from the issuer's certificate. - */ - issuer_params_size = MAX_PUBLIC_PARAMS_SIZE; - ret = - MHD__gnutls_x509_crt_get_mpis (issuer, issuer_params, - &issuer_params_size); - if (ret < 0) - { - MHD_gnutls_assert (); - return ret; - } - - ret = - verify_sig (tbs, signature, - MHD_gnutls_x509_crt_get_pk_algorithm (issuer, NULL), - issuer_params, issuer_params_size); - if (ret < 0) - { - MHD_gnutls_assert (); - } - - /* release all allocated MPIs - */ - for (i = 0; i < issuer_params_size; i++) - { - MHD_gtls_mpi_release (&issuer_params[i]); - } - - return ret; -} - -/** - * MHD_gnutls_x509_crt_list_verify - This function verifies the given certificate list - * @cert_list: is the certificate list to be verified - * @cert_list_length: holds the number of certificate in cert_list - * @CA_list: is the CA list which will be used in verification - * @CA_list_length: holds the number of CA certificate in CA_list - * @CRL_list: holds a list of CRLs. - * @CRL_list_length: the length of CRL list. - * @flags: Flags that may be used to change the verification algorithm. Use OR of the MHD_gnutls_certificate_verify_flags enumerations. - * @verify: will hold the certificate verification output. - * - * This function will try to verify the given certificate list and return its status. - * Note that expiration and activation dates are not checked - * by this function, you should check them using the appropriate functions. - * - * If no flags are specified (0), this function will use the - * basicConstraints (2.5.29.19) PKIX extension. This means that only a certificate - * authority is allowed to sign a certificate. - * - * You must also check the peer's name in order to check if the verified - * certificate belongs to the actual peer. - * - * The certificate verification output will be put in @verify and will be - * one or more of the MHD_gnutls_certificate_status_t enumerated elements bitwise or'd. - * For a more detailed verification status use MHD_gnutls_x509_crt_verify() per list - * element. - * - * GNUTLS_CERT_INVALID: the certificate chain is not valid. - * - * GNUTLS_CERT_REVOKED: a certificate in the chain has been revoked. - * - * Returns 0 on success and a negative value in case of an error. - * - **/ -int -MHD_gnutls_x509_crt_list_verify (const MHD_gnutls_x509_crt_t * cert_list, - int cert_list_length, - const MHD_gnutls_x509_crt_t * CA_list, - int CA_list_length, - const MHD_gnutls_x509_crl_t * CRL_list, - int CRL_list_length, - unsigned int flags, unsigned int *verify) -{ - if (cert_list == NULL || cert_list_length == 0) - return GNUTLS_E_NO_CERTIFICATE_FOUND; - - /* Verify certificate - */ - *verify = MHD__gnutls_x509_verify_certificate (cert_list, cert_list_length, - CA_list, CA_list_length, - CRL_list, CRL_list_length, - flags); - - return 0; -} -