summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2001-06-15 16:57:20 +0000
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2001-06-15 16:57:20 +0000
commit6bbad670fc75632fd03a9cf56dc5e0ce6a196d4c (patch)
treec7b902dd3c26dc5c73e72d651084adb884b5ad31
parent962ec6bdec17f6fea0603f50bcd418f5e4d0b01d (diff)
downloadgnutls-6bbad670fc75632fd03a9cf56dc5e0ce6a196d4c.tar.gz
several additions in order to support KX_RSA and X509PKI.
-rw-r--r--doc/Makefile.am5
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/auth_rsa.c243
-rw-r--r--lib/auth_x509.h11
-rwxr-xr-xlib/cert_asn1.h6
-rw-r--r--lib/gnutls.h.in9
-rw-r--r--lib/gnutls_datum.c42
-rw-r--r--lib/gnutls_datum.h4
-rw-r--r--lib/gnutls_hash_int.c4
-rw-r--r--lib/gnutls_hash_int.h4
-rw-r--r--lib/gnutls_int.h56
-rw-r--r--lib/gnutls_kx.c10
12 files changed, 341 insertions, 57 deletions
diff --git a/doc/Makefile.am b/doc/Makefile.am
index 7bbe5cc8ff..fed12235a5 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -1,8 +1,5 @@
-EXTRA_DIST = TODO gnutls.3 gnutls-api.txt gnutls-api.html
-man_MANS = gnutls.3
+EXTRA_DIST = TODO gnutls-api.txt gnutls-api.html
-gnutls.3:
- @scripts/gdoc -man ../lib/*.c > gnutls.3
gnutls-api: gnutls-api.html gnutls-api.txt
gnutls-api.html:
@scripts/gdoc -html ../lib/*.c > gnutls-api.html
diff --git a/lib/Makefile.am b/lib/Makefile.am
index b69ea0a000..1e81f3857a 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -13,7 +13,7 @@ EXTRA_DIST = debug.h gnutls_compress.h defines.h gnutls_plaintext.h \
gnutls_auth_int.h crypt_bcrypt.h gnutls_random.h crypt_srpsha1.h \
cert_b64.h gnutls_srp.h auth_srp.h auth_srp_passwd.h gnutls_v2_compat.h \
crypt.h libgnutls-config.in libgnutls.m4 gnutls.h.in gnutls_errors_int.h \
- cert_asn1.h cert_der.h
+ cert_asn1.h cert_der.h gnutls_datum.h auth_x509.c
lib_LTLIBRARIES = libgnutls.la
libgnutls_la_SOURCES = gnutls.c gnutls_compress.c debug.c gnutls_plaintext.c \
gnutls_cipher.c gnutls_buffers.c gnutls_handshake.c gnutls_num.c \
@@ -23,6 +23,6 @@ libgnutls_la_SOURCES = gnutls.c gnutls_compress.c debug.c gnutls_plaintext.c \
auth_anon.c auth_dhe_dss.c gnutls_extensions.c ext_srp.c gnutls_auth.c \
crypt_bcrypt.c crypt.c gnutls_random.c crypt_srpsha1.c gnutls_srp.c \
auth_srp.c auth_srp_passwd.c gnutls_v2_compat.c auth_srp_sb64.c \
- cert_ASN.y cert_asn1.c cert_der.c
+ cert_ASN.y cert_asn1.c cert_der.c gnutls_datum.c auth_rsa.c
libgnutls_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
diff --git a/lib/auth_rsa.c b/lib/auth_rsa.c
new file mode 100644
index 0000000000..932c7b2c7b
--- /dev/null
+++ b/lib/auth_rsa.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2000,2001 Nikos Mavroyanopoulos
+ *
+ * This file is part of GNUTLS.
+ *
+ * GNUTLS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUTLS 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <defines.h>
+#include "gnutls_int.h"
+#include "gnutls_auth_int.h"
+#include "gnutls_errors.h"
+#include "gnutls_dh.h"
+#include "auth_anon.h"
+#include "gnutls_num.h"
+#include "cert_asn1.h"
+#include "cert_der.h"
+#include "gnutls_datum.h"
+#include "auth_x509.h"
+
+int gen_rsa_server_kx(GNUTLS_KEY, opaque **);
+
+MOD_AUTH_STRUCT rsa_auth_struct = {
+ "RSA",
+ gen_rsa_server_kx,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+typedef struct {
+ gnutls_datum rsa_modulus;
+ gnutls_datum rsa_exponent;
+} RSA_Params;
+
+/* This function will calculate the SHA/MD5 signature in server kx.
+ * This is needed by the protocol.
+ */
+int _gnutls_calc_rsa_signature( GNUTLS_KEY key, const opaque* data, int data_size, opaque* dst) {
+ void* md5;
+ void* sha;
+ int ret = 0;
+ GNUTLS_MAC_HANDLE td;
+
+ td = gnutls_hash_init(GNUTLS_MAC_MD5);
+ if (td==GNUTLS_HASH_FAILED) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ gnutls_hash( td, key->client_random, 32);
+ gnutls_hash( td, key->server_random, 32);
+ gnutls_hash( td, data, data_size);
+
+ md5 = gnutls_hash_deinit(td);
+ if (md5==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ memcpy( dst, md5, 16);
+ gnutls_free(md5);
+
+
+ td = gnutls_hash_init(GNUTLS_MAC_SHA);
+ if (td==GNUTLS_HASH_FAILED) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+ gnutls_hash( td, key->client_random, 32);
+ gnutls_hash( td, key->server_random, 32);
+ gnutls_hash( td, data, data_size);
+
+ sha = gnutls_hash_deinit(td);
+ if (sha==NULL) {
+ gnutls_assert();
+ return GNUTLS_E_MEMORY_ERROR;
+ }
+
+ memcpy( &dst[16], sha, 20);
+ gnutls_free(sha);
+
+ return ret;
+}
+
+
+#define dat_set( d,s,len) d.data=gnutls_malloc(len); \
+ if (d.data==NULL) return GNUTLS_E_MEMORY_ERROR; \
+ memcpy(d.data, s, len); d.size = len;
+
+/* This function reads the RSA parameters from the given(?) certificate.
+ */
+static int _gnutls_get_rsa_params( GNUTLS_KEY key, RSA_Params * params, gnutls_datum cert)
+{
+ int ret = 0, result;
+ opaque str[5*1024];
+ int len = sizeof(str);
+
+ create_structure("certificate2", "PKIX1Explicit88.Certificate");
+
+ result = get_der("certificate2", cert.data, cert.size);
+ if (result != ASN_OK) {
+ gnutls_assert();
+ return GNUTLS_E_PARSING_ERROR;
+ }
+
+ /* Verify sign */
+ result =
+ read_value("certificate2.tbsCertificate.subjectPublicKeyInfo.algorithm", str, &len);
+ if (result != ASN_OK) {
+ gnutls_assert();
+ delete_structure("certificate2");
+ return GNUTLS_E_PARSING_ERROR;
+ }
+
+ if (!strcmp(str, "111")) { /* pkix-1 1 - RSA */
+ len = sizeof(str);
+ result =
+ read_value("certificate2.tbsCertificate.subjectPublicKeyInfo.parameters", str, &len);
+ delete_structure("certificate2");
+
+ if (result != ASN_OK) {
+ gnutls_assert();
+ delete_structure("certificate2");
+ return GNUTLS_E_PARSING_ERROR;
+ }
+
+ create_structure("rsapublickey", "PKIX1Explicit88.RSAPublicKey");
+ result = get_der("rsapublickey", str, len);
+ if (result != ASN_OK) {
+ gnutls_assert();
+ delete_structure("rsapublickey");
+ return GNUTLS_E_PARSING_ERROR;
+ }
+
+ result =
+ read_value("rsapublickey.modulus", str, &len);
+ if (result != ASN_OK) {
+ gnutls_assert();
+ delete_structure("rsapublickey");
+ return GNUTLS_E_PARSING_ERROR;
+ }
+
+ if (gcry_mpi_scan(&key->A,
+ GCRYMPI_FMT_USG, str, &len) != 0) {
+ gnutls_assert();
+ delete_structure("rsapublickey");
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+ dat_set(params->rsa_modulus, str, len);
+
+ len = sizeof(str);
+ result =
+ read_value("rsapublickey.publicExponent", str, &len);
+ if (result != ASN_OK) {
+ gnutls_assert();
+ delete_structure("rsapublickey");
+ gnutls_free(params->rsa_modulus.data);
+ gcry_mpi_release(key->A);
+ return GNUTLS_E_PARSING_ERROR;
+ }
+
+ if (gcry_mpi_scan(&key->B,
+ GCRYMPI_FMT_USG, str, &len) != 0) {
+ gnutls_assert();
+ gcry_mpi_release(key->A);
+ gnutls_free(params->rsa_modulus.data);
+ delete_structure("rsapublickey");
+ return GNUTLS_E_MPI_SCAN_FAILED;
+ }
+ dat_set(params->rsa_exponent, str, len);
+
+ delete_structure("rsapublickey");
+
+ }
+
+ delete_structure("certificate2");
+
+ return ret;
+}
+
+int gen_rsa_server_kx(GNUTLS_KEY key, opaque ** data)
+{
+ RSA_Params params;
+ const X509PKI_SERVER_CREDENTIALS *cred;
+ int ret;
+ opaque* pdata;
+
+ cred = _gnutls_get_cred(key, GNUTLS_X509PKI, NULL);
+ if (cred == NULL) {
+ gnutls_assert();
+ return GNUTLS_E_INSUFICIENT_CRED;
+ }
+
+ ret =
+ _gnutls_get_rsa_params(key, &params, cred->cert_list[0]);
+
+ if (ret < 0) {
+ gnutls_assert();
+ return ret;
+ }
+
+ ret = params.rsa_modulus.size +
+ params.rsa_modulus.size + 16 + 20 + 4;
+ (*data) = gnutls_malloc( ret);
+
+ pdata = (*data);
+ if (pdata == NULL) return GNUTLS_E_MEMORY_ERROR;
+
+ WRITEdatum16(pdata, params.rsa_modulus);
+ pdata += params.rsa_modulus.size;
+
+ WRITEdatum16(pdata, params.rsa_exponent);
+ pdata += params.rsa_exponent.size;
+
+ ret = _gnutls_calc_rsa_signature( key, (*data), ret-20-16, pdata);
+ if (ret< 0) {
+ gnutls_free((*data));
+ gnutls_assert();
+ return ret;
+ }
+
+ return ret;
+}
+
diff --git a/lib/auth_x509.h b/lib/auth_x509.h
new file mode 100644
index 0000000000..d7dcd2d3a0
--- /dev/null
+++ b/lib/auth_x509.h
@@ -0,0 +1,11 @@
+/* this is not to be included by gnutls_anon.c */
+extern MOD_AUTH_STRUCT x509pki_auth_struct;
+
+typedef struct {
+ gnutls_datum * cert_list;
+ int cert_list_size;
+} X509PKI_SERVER_CREDENTIALS;
+
+typedef struct {
+ int dh_bits;
+} X509PKI_AUTH_INFO;
diff --git a/lib/cert_asn1.h b/lib/cert_asn1.h
index b29a7a80dc..a1d8354294 100755
--- a/lib/cert_asn1.h
+++ b/lib/cert_asn1.h
@@ -167,5 +167,11 @@ delete_tree2(node_asn *root);
int
append_sequence_set(node_asn *node);
+int
+create_structure(char *dest_name,char *source_name);
+
+int
+delete_structure(char *root_name);
+
#endif
diff --git a/lib/gnutls.h.in b/lib/gnutls.h.in
index e3d1a4759c..174a602928 100644
--- a/lib/gnutls.h.in
+++ b/lib/gnutls.h.in
@@ -47,6 +47,11 @@ typedef enum AlertDescription { GNUTLS_CLOSE_NOTIFY, GNUTLS_UNEXPECTED_MESSAGE=1
struct GNUTLS_STATE_INT;
typedef struct GNUTLS_STATE_INT* GNUTLS_STATE;
+typedef struct {
+ unsigned char * data;
+ int size;
+} gnutls_datum;
+
/* internal functions */
int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end);
@@ -136,5 +141,9 @@ typedef struct {
int dh_bits;
} ANON_AUTH_INFO;
+typedef struct {
+ gnutls_datum * cert_list;
+ int cert_list_size;
+} X509PKI_SERVER_CREDENTIALS;
/* error codes appended here */
diff --git a/lib/gnutls_datum.c b/lib/gnutls_datum.c
new file mode 100644
index 0000000000..8e137dcb18
--- /dev/null
+++ b/lib/gnutls_datum.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2001 Nikos Mavroyanopoulos
+ *
+ * This file is part of GNUTLS.
+ *
+ * GNUTLS is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GNUTLS 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <defines.h>
+#include <gnutls_int.h>
+#include <gnutls_num.h>
+#include <gnutls_datum.h>
+#include <gnutls_errors.h>
+
+void WRITEdatum16( opaque* dest, gnutls_datum dat) {
+ WRITEuint16( dat.size, dest);
+ memcpy( &dest[2], dat.data, dat.size);
+}
+void WRITEdatum24( opaque* dest, gnutls_datum dat) {
+ WRITEuint24( dat.size, dest);
+ memcpy( &dest[3], dat.data, dat.size);
+}
+void WRITEdatum32( opaque* dest, gnutls_datum dat) {
+ WRITEuint32( dat.size, dest);
+ memcpy( &dest[4], dat.data, dat.size);
+}
+void WRITEdatum8( opaque* dest, gnutls_datum dat) {
+ dest[0] = (uint8) dat.size;
+ memcpy( &dest[1], dat.data, dat.size);
+}
diff --git a/lib/gnutls_datum.h b/lib/gnutls_datum.h
new file mode 100644
index 0000000000..2462acd648
--- /dev/null
+++ b/lib/gnutls_datum.h
@@ -0,0 +1,4 @@
+void WRITEdatum16( opaque* dest, gnutls_datum dat);
+void WRITEdatum24( opaque* dest, gnutls_datum dat);
+void WRITEdatum32( opaque* dest, gnutls_datum dat);
+void WRITEdatum8( opaque* dest, gnutls_datum dat);
diff --git a/lib/gnutls_hash_int.c b/lib/gnutls_hash_int.c
index 42e0eaff7b..464baa8aa8 100644
--- a/lib/gnutls_hash_int.c
+++ b/lib/gnutls_hash_int.c
@@ -99,7 +99,7 @@ int gnutls_hash_get_algo_len(MACAlgorithm algorithm)
}
-int gnutls_hash(GNUTLS_MAC_HANDLE handle, void *text, int textlen)
+int gnutls_hash(GNUTLS_MAC_HANDLE handle, const void *text, int textlen)
{
#ifdef USE_MHASH
mhash(handle->handle, text, textlen);
@@ -210,7 +210,7 @@ int gnutls_hmac_get_algo_len(MACAlgorithm algorithm)
}
-int gnutls_hmac(GNUTLS_MAC_HANDLE handle, void *text, int textlen)
+int gnutls_hmac(GNUTLS_MAC_HANDLE handle, const void *text, int textlen)
{
#ifdef USE_MHASH
diff --git a/lib/gnutls_hash_int.h b/lib/gnutls_hash_int.h
index dd2b7ce53f..ae516325d3 100644
--- a/lib/gnutls_hash_int.h
+++ b/lib/gnutls_hash_int.h
@@ -49,7 +49,7 @@ typedef GNUTLS_MAC_HANDLE_INT* GNUTLS_MAC_HANDLE;
GNUTLS_MAC_HANDLE gnutls_hmac_init( MACAlgorithm algorithm, void* key, int keylen);
int gnutls_hmac_get_algo_len(MACAlgorithm algorithm);
-int gnutls_hmac(GNUTLS_MAC_HANDLE handle, void* text, int textlen);
+int gnutls_hmac(GNUTLS_MAC_HANDLE handle, const void* text, int textlen);
void* gnutls_hmac_deinit( GNUTLS_MAC_HANDLE handle);
GNUTLS_MAC_HANDLE gnutls_mac_init_ssl3( MACAlgorithm algorithm, void* key, int keylen);
@@ -57,7 +57,7 @@ void* gnutls_mac_deinit_ssl3( GNUTLS_MAC_HANDLE handle);
GNUTLS_MAC_HANDLE gnutls_hash_init(MACAlgorithm algorithm);
int gnutls_hash_get_algo_len(MACAlgorithm algorithm);
-int gnutls_hash(GNUTLS_MAC_HANDLE handle, void* text, int textlen);
+int gnutls_hash(GNUTLS_MAC_HANDLE handle, const void* text, int textlen);
void* gnutls_hash_deinit(GNUTLS_MAC_HANDLE handle);
void *gnutls_ssl3_generate_random(void *secret, int secret_len, void *random, int random_len, int bytes);
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index 84cef16a69..58b682e461 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -139,6 +139,10 @@ typedef struct {
MPI b;
MPI a;
MPI x;
+ /* RSA:
+ * modulus is A
+ * exponent is B
+ */
/* this is used to hold the peers authentication data
*/
@@ -147,6 +151,10 @@ typedef struct {
uint8 crypt_algo;
+ /* These are needed in RSA and DH signature calculation
+ */
+ opaque server_random[32];
+ opaque client_random[32];
AUTH_CRED* cred; /* used in srp, etc */
} GNUTLS_KEY_A;
typedef GNUTLS_KEY_A* GNUTLS_KEY;
@@ -287,24 +295,9 @@ typedef struct {
opaque* fragment;
} GNUTLSCompressed;
-/* This is used for both block ciphers and stream ciphers. In stream ciphers
- * the padding is just ignored.
- */
-typedef struct {
- opaque* content;
- opaque* MAC;
- uint8* padding;
- uint8 padding_length;
-} GNUTLS_GenericBlockCipher;
-
-typedef struct {
- opaque* content;
- opaque* MAC;
-} GNUTLS_GenericStreamCipher;
-
typedef struct {
uint8 type;
- ProtocolVersion version;
+ ProtocolVersion version;
uint16 length;
void* fragment; /* points GenericStreamCipher
* or GenericBlockCipher
@@ -312,37 +305,6 @@ typedef struct {
} GNUTLSCiphertext;
-/* Handshake protocol */
-
-
-typedef struct {
- HandshakeType msg_type;
- uint24 length;
- void* body;
-} GNUTLS_Handshake;
-
-typedef struct {
- uint32 gmt_unix_time;
- opaque random_bytes[28];
-} GNUTLS_random;
-
-
-typedef struct {
- ProtocolVersion client_version;
- GNUTLS_random random;
- opaque* session_id;
- GNUTLS_CipherSuite* cipher_suites;
- CompressionMethod* compression_methods;
-} GNUTLS_ClientHello;
-
-typedef struct {
- ProtocolVersion server_version;
- GNUTLS_random random;
- opaque* session_id;
- GNUTLS_CipherSuite cipher_suite;
- CompressionMethod compression_method;
-} GNUTLS_ServerHello;
-
/* functions */
int _gnutls_send_alert( int cd, GNUTLS_STATE state, AlertLevel level, AlertDescription desc);
int gnutls_close(int cd, GNUTLS_STATE state);
diff --git a/lib/gnutls_kx.c b/lib/gnutls_kx.c
index 3c757c9473..9d6d0a26dd 100644
--- a/lib/gnutls_kx.c
+++ b/lib/gnutls_kx.c
@@ -91,6 +91,16 @@ int _gnutls_send_server_kx_message(int cd, GNUTLS_STATE state)
#ifdef HARD_DEBUG
fprintf(stderr, "Sending server KX message\n");
#endif
+
+
+ if (state->gnutls_internals.auth_struct->gnutls_generate_server_kx==NULL)
+ return 0;
+
+ /* copy random bytes - some algorithms need that.
+ */
+ memcpy( state->gnutls_key->server_random, state->security_parameters.server_random, 32);
+ memcpy( state->gnutls_key->client_random, state->security_parameters.client_random, 32);
+
data_size = state->gnutls_internals.auth_struct->gnutls_generate_server_kx( state->gnutls_key, &data);
if (data_size < 0) {