dnl Gnutls Version
GNUTLS_MAJOR_VERSION=0
GNUTLS_MINOR_VERSION=9
-GNUTLS_MICRO_VERSION=3
+GNUTLS_MICRO_VERSION=4
GNUTLS_VERSION=$GNUTLS_MAJOR_VERSION.$GNUTLS_MINOR_VERSION.$GNUTLS_MICRO_VERSION
AC_DEFINE_UNQUOTED(GNUTLS_VERSION, "$GNUTLS_VERSION", [version of gnutls])
for (i = 0; i < x; i++) {
if (memcmp(ciphers[i].CipherSuite, &data[j], 2) ==
0) {
- _gnutls_handshake_log("HSK: Selected cipher suite: ");
- _gnutls_handshake_log("%s\n",
+ _gnutls_handshake_log("HSK: Selected cipher suite: %s\n",
_gnutls_cipher_suite_get_name(*
((GNUTLS_CipherSuite *) & data[j])));
memcpy(session->security_parameters.current_cipher_suite.CipherSuite, ciphers[i].CipherSuite, 2);
*/
_gnutls_set_adv_version( session, hver);
- /* Some implementations do not interoperate if we send a
+ /* Some old implementations do not interoperate if we send a
* different version in the record layer.
* It seems they prefer to read the record's version
* as the one we actually requested.
- * The proper behaviour is to use the one in the client hello
+ * The proper behaviour is to use the one in the client hello
* handshake packet and ignore the one in the packet's record
* header.
*/
- if (session->internals.default_record_version==0)
- _gnutls_set_current_version(session, hver);
- else _gnutls_set_current_version(session,
- session->internals.default_record_version);
+ _gnutls_set_current_version(session, hver);
/* In order to know when this session was initiated.
*/
/*
- * Copyright (C) 2000,2001,2002,2003 Nikos Mavroyanopoulos
+ * Copyright (C) 2000,2001,2002,2003 Nikos Mavroyanopoulos
*
- * This file is part of GNUTLS.
+ * 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
/* This holds the default version that our first
* record packet will have. */
- gnutls_protocol_version default_record_version;
+ opaque default_record_version[2];
int cbc_protection_hack;
*
**/
void gnutls_transport_set_ptr2(gnutls_session session, gnutls_transport_ptr recv_ptr,
- gnutls_transport_ptr send_ptr) {
+ gnutls_transport_ptr send_ptr)
+{
session->internals.transport_send_ptr = send_ptr;
session->internals.transport_recv_ptr = recv_ptr;
}
* PULL). This must have been set using gnutls_transport_set_ptr().
*
**/
-gnutls_transport_ptr gnutls_transport_get_ptr(gnutls_session session) {
+gnutls_transport_ptr gnutls_transport_get_ptr(gnutls_session session)
+{
return session->internals.transport_recv_ptr;
}
return 0;
}
+/* Copies the record version into the headers. The
+ * version, must have 2 bytes at least.
+ */
+inline static void copy_record_version( gnutls_session session, HandshakeType htype,
+ opaque version[2])
+{
+gnutls_protocol_version lver;
+
+ if (htype != GNUTLS_CLIENT_HELLO || session->internals.default_record_version[0] == 0) {
+ lver = gnutls_protocol_get_version( session);
+
+ version[0] = _gnutls_version_get_major( lver);
+ version[1] = _gnutls_version_get_minor( lver);
+ } else {
+ version[0] = session->internals.default_record_version[0];
+ version[1] = session->internals.default_record_version[1];
+ }
+}
+
static
ssize_t _gnutls_create_empty_record( gnutls_session session, ContentType type,
opaque* erecord, unsigned int erecord_size)
int retval;
int data2send;
uint8 headers[5];
- gnutls_protocol_version lver;
if (type!=GNUTLS_APPLICATION_DATA ||
_gnutls_cipher_is_block( gnutls_cipher_get(session))!=CIPHER_BLOCK)
*/
return 0;
- headers[0]=type;
+ headers[0] = type;
- lver = gnutls_protocol_get_version(session);
- if (lver==GNUTLS_VERSION_UNKNOWN) {
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
- }
-
- headers[1]=_gnutls_version_get_major( lver);
- headers[2]=_gnutls_version_get_minor( lver);
+ copy_record_version( session, (HandshakeType)(-1), &headers[1]);
data2send = 0;
int data2send_size;
uint8 headers[5];
const uint8 *data=_data;
- gnutls_protocol_version lver;
int erecord_size = 0;
opaque* erecord = NULL;
- headers[0]=type;
+ headers[0] = type;
- lver = gnutls_protocol_get_version(session);
- if (lver==GNUTLS_VERSION_UNKNOWN) {
- gnutls_assert();
- return GNUTLS_E_INTERNAL_ERROR;
- }
+ /* Use the default record version, if it is
+ * set.
+ */
+ copy_record_version( session, htype, &headers[1]);
- headers[1]=_gnutls_version_get_major( lver);
- headers[2]=_gnutls_version_get_minor( lver);
_gnutls_record_log( "REC[%x]: Sending Packet[%d] %s(%d) with length: %d\n",
session, (int) _gnutls_uint64touint32(&session->connection_state.write_sequence_number), _gnutls_packet2str(type), type, sizeofdata);
* content type.
*/
static int _gnutls_check_record_headers( gnutls_session session, uint8 headers[RECORD_HEADER_SIZE], ContentType type,
- HandshakeType htype, /*output*/ ContentType *recv_type, gnutls_protocol_version *version, uint16 *length, uint16* header_size) {
+ HandshakeType htype, /*output*/ ContentType *recv_type, opaque version[2], uint16 *length, uint16* header_size) {
/* Read the first two bytes to determine if this is a
* version 2 message
/* if msb set and expecting handshake message
* it should be SSL 2 hello
*/
- *version = GNUTLS_VERSION_UNKNOWN; /* assume unknown version */
+ version[0] = 3; /* assume SSL 3.0 */
+ version[1] = 0;
+
*length = (((headers[0] & 0x7f) << 8)) | headers[1];
/* SSL 2.0 headers */
/* version 3.x
*/
*recv_type = headers[0];
-#ifdef CHECK_RECORD_VERSION
- *version = _gnutls_version_get( headers[1], headers[2]);
-#endif
+ version[0] = headers[1];
+ version[1] = headers[2];
/* No DECR_LEN, since headers has enough size.
*/
* negotiated in the handshake.
*/
inline
-static int _gnutls_check_record_version( gnutls_session session, HandshakeType htype, gnutls_protocol_version version)
+static int _gnutls_check_record_version( gnutls_session session, HandshakeType htype, opaque version[2])
{
#ifdef CHECK_RECORD_VERSION
- if ( (htype!=GNUTLS_CLIENT_HELLO && htype!=GNUTLS_SERVER_HELLO) && gnutls_protocol_get_version(session) != version) {
- gnutls_assert();
+ if ( (htype!=GNUTLS_CLIENT_HELLO && htype!=GNUTLS_SERVER_HELLO) &&
+ gnutls_protocol_get_version(session) != _gnutls_version_get( version[0], version[1])) {
+ gnutls_assert();
_gnutls_record_log( "REC[%x]: INVALID VERSION PACKET: (%d) %d.%d\n",
- session, htype, _gnutls_version_get_major(version), _gnutls_version_get_minor(version));
+ session, htype, version[0], version[1]);
return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
}
{
uint8 *tmpdata;
int tmplen;
- gnutls_protocol_version version;
+ opaque version[2];
uint8 *headers;
ContentType recv_type;
uint16 length;
return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
- if ( (ret=_gnutls_check_record_headers( session, headers, type, htype, &recv_type, &version, &length, &header_size)) < 0) {
+ if ( (ret=_gnutls_check_record_headers( session, headers, type, htype, &recv_type, version, &length, &header_size)) < 0) {
gnutls_assert();
return ret;
}
/*-
* _gnutls_record_set_default_version - Used to set the default version for the first record packet
* @session: is a &gnutls_session structure.
- * @version: is a tls version
+ * @major: is a tls major version
+ * @minor: is a tls minor version
*
* This function sets the default version that we will use in the first
* record packet (client hello). This function is only useful to people
* that know TLS internals and want to debug other implementations.
*
-*/
-void _gnutls_record_set_default_version(gnutls_session session, gnutls_protocol_version version)
+void _gnutls_record_set_default_version(gnutls_session session,
+ unsigned char major, unsigned char minor)
{
- session->internals.default_record_version = version;
+ session->internals.default_record_version[0] = major;
+ session->internals.default_record_version[1] = minor;
}
/**
#include <gnutls_int.h>
-void _gnutls_record_set_default_version(gnutls_session session, gnutls_protocol_version version);
-
void _gnutls_session_cert_type_set( gnutls_session session, gnutls_certificate_type);
gnutls_kx_algorithm gnutls_kx_get( gnutls_session session);
gnutls_cipher_algorithm gnutls_cipher_get( gnutls_session session);
move=RIGHT;
break;
case TYPE_OBJECT_ID:
- if(p->value==NULL){
+ if((p->type&CONST_DEFAULT) && (p->value==NULL)){
+ counter=counter_old;
+ max_len=max_len_old;
+ }
+ else{
+ if(p->value==NULL){
_asn1_error_description_value_not_found(p,ErrorDescription);
return ASN1_VALUE_NOT_FOUND;
+ }
+ len2=max_len;
+ ris=_asn1_objectid_der(p->value,der+counter,&len2);
+ if(ris==ASN1_MEM_ALLOC_ERROR) return ris;
+ max_len-=len2;
+ counter+=len2;
}
- len2=max_len;
- ris=_asn1_objectid_der(p->value,der+counter,&len2);
- if(ris==ASN1_MEM_ALLOC_ERROR) return ris;
- max_len-=len2;
- counter+=len2;
move=RIGHT;
break;
case TYPE_TIME:
for(k=0;k<strlen(value);k++)
if((!isdigit(value[k])) && (value[k]!='.') && (value[k]!='+'))
return ASN1_VALUE_NOT_VALID;
+ if(node->type&CONST_DEFAULT){
+ p=node->down;
+ while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
+ if(!strcmp(value,p->value)){
+ _asn1_set_value(node,NULL,0);
+ break;
+ }
+ }
_asn1_set_value(node,value,strlen(value)+1);
break;
case TYPE_TIME:
p=p->right;
}
*len = strlen(value) + 1;
- } else {
+ }
+ else if((node->type&CONST_DEFAULT) && (node->value==NULL)){
+ p=node->down;
+ while(type_field(p->type)!=TYPE_DEFAULT) p=p->right;
+ PUT_STR_VALUE(value, value_size, p->value);
+ }
+ else {
PUT_STR_VALUE(value, value_size, node->value);
}
break;
#include <mem.h>
-#define LIBTASN1_VERSION "0.2.3"
+#define LIBTASN1_VERSION "0.2.4"
#define MAX32 4294967295
#define MAX24 16777215
extern "C" {
#endif
-#define LIBTASN1_VERSION "0.2.3"
+#define LIBTASN1_VERSION "0.2.4"
#include <sys/types.h>
#include <time.h>
_asn1_expand_object_id(ASN1_TYPE node)
{
node_asn *p,*p2,*p3,*p4,*p5;
- char name_root[129],name2[129];
+ char name_root[MAX_NAME_SIZE],name2[2*MAX_NAME_SIZE+1];
int move;
if(node==NULL) return ASN1_ELEMENT_NOT_FOUND;
if(move==UP) p=_asn1_find_up(p);
}
+
+ /*******************************/
+ /* expand DEFAULT */
+ /*******************************/
+ p=node;
+ move=DOWN;
+
+ while(!((p==node) && (move==UP))){
+ if(move!=UP){
+ if((type_field(p->type)==TYPE_OBJECT_ID) &&
+ (p->type&CONST_DEFAULT)){
+ p2=p->down;
+ if(p2 && (type_field(p2->type)==TYPE_DEFAULT)){
+ _asn1_str_cpy(name2, sizeof(name2), name_root);
+ _asn1_str_cat(name2, sizeof(name2), ".");
+ _asn1_str_cat(name2, sizeof(name2), p2->value);
+ p3=_asn1_find_node(node,name2);
+ if(!p3 || (type_field(p3->type)!=TYPE_OBJECT_ID) ||
+ !(p3->type&CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND;
+ p4=p3->down;
+ name2[0]=0;
+ while(p4){
+ if(type_field(p4->type)==TYPE_CONSTANT){
+ if(name2[0]) _asn1_str_cat(name2,sizeof(name2),".");
+ _asn1_str_cat(name2,sizeof(name2),p4->value);
+ }
+ p4=p4->right;
+ }
+ _asn1_set_value(p2,name2,strlen(name2)+1);
+ }
+ }
+ move=DOWN;
+ }
+ else move=RIGHT;
+
+ if(move==DOWN){
+ if(p->down) p=p->down;
+ else move=RIGHT;
+ }
+
+ if(p==node) {move=UP; continue;}
+
+ if(move==RIGHT){
+ if(p->right) p=p->right;
+ else move=UP;
+ }
+ if(move==UP) p=_asn1_find_up(p);
+ }
+
return ASN1_SUCCESS;
}
return ASN1_IDENTIFIER_NOT_FOUND;
}
}
+ else if((type_field(p->type)==TYPE_OBJECT_ID) &&
+ (p->type&CONST_DEFAULT)){
+ p2=p->down;
+ if(p2 && (type_field(p2->type)==TYPE_DEFAULT)){
+ _asn1_str_cpy(name2, sizeof(name2), node->name);
+ _asn1_str_cat(name2, sizeof(name2), ".");
+ _asn1_str_cat(name2, sizeof(name2), p2->value);
+ strcpy(_asn1_identifierMissing,p2->value);
+ p2=_asn1_find_node(node,name2);
+ if(!p2 || (type_field(p2->type)!=TYPE_OBJECT_ID) ||
+ !(p2->type&CONST_ASSIGN))
+ return ASN1_IDENTIFIER_NOT_FOUND;
+ else
+ _asn1_identifierMissing[0]=0;
+ }
+ }
else if((type_field(p->type)==TYPE_OBJECT_ID) &&
(p->type&CONST_ASSIGN)){
p2=p->down;
},
iterationCount INTEGER (1..MAX),
keyLength INTEGER (1..MAX) OPTIONAL,
- prf AlgorithmIdentifier OPTIONAL -- DEFAULT pkcs-5-algid-hmacWithSHA1
+ prf AlgorithmIdentifier OPTIONAL -- DEFAULT pkcs-5-id-hmacWithSHA1
}
END
return ret;
}
-void _gnutls_record_set_default_version(gnutls_session session, gnutls_protocol_version version);
+void _gnutls_record_set_default_version(gnutls_session session, unsigned char major,
+ unsigned char minor);
int test_version_rollback( gnutls_session session) {
int ret;
ADD_ALL_MACS(session);
ADD_ALL_KX(session);
gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
- _gnutls_record_set_default_version( session, GNUTLS_SSL3);
+ _gnutls_record_set_default_version( session, 3, 0);
ret = do_handshake( session);
if (ret!=SUCCEED) return ret;
return SUCCEED;
}
+/* See if the server tolerates out of bounds
+ * record layer versions in the first client hello
+ * message.
+ */
+int test_version_oob( gnutls_session session) {
+int ret;
+ /* here we enable both SSL 3.0 and TLS 1.0
+ * and we connect using a 5.5 record version.
+ */
+ ADD_ALL_CIPHERS(session);
+ ADD_ALL_COMP(session);
+ ADD_ALL_CERTTYPES(session);
+ ADD_ALL_PROTOCOLS(session);
+ ADD_ALL_MACS(session);
+ ADD_ALL_KX(session);
+ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred);
+ _gnutls_record_set_default_version( session, 5, 5);
+
+ ret = do_handshake( session);
+ return ret;
+}
+
void _gnutls_rsa_pms_set_version(gnutls_session session, unsigned char major,
unsigned char minor);
int test_server_cas( gnutls_session state);
int test_session_resume2( gnutls_session state);
int test_rsa_pms_version_check( gnutls_session session);
+int test_version_oob( gnutls_session session);
#define GERR(ret) fprintf(stderr, "*** Error: %s\n", gnutls_strerror(ret))
/*
- * Copyright (C) 2000,2001,2002 Nikos Mavroyanopoulos
+ * Copyright (C) 2000,2001,2002,2003 Nikos Mavroyanopoulos
*
* This file is part of GNUTLS.
*
{ "whether the server ignores the RSA PMS version", test_rsa_pms_version_check, "yes", "no", "dunno"},
{ "whether the server can accept Hello Extensions", test_hello_extension, "yes", "no", "dunno"},
{ "whether the server can accept cipher suites not in SSL 3.0 spec", test_unknown_ciphersuites, "yes", "no", "dunno"},
+ { "whether the server can accept a bogus TLS record version in the client hello", test_version_oob, "yes", "no", "dunno"},
{ "for certificate information", test_certificate, "", "", "" },
{ "for trusted CAs", test_server_cas, "", "", "" },
{ "whether the server understands TLS closure alerts", test_bye, "yes", "no", "partially"},