* Add Kerberos support (who wants that?)
* Audit the code (volunteers?)
* Tools for processing/generating certificates
+* Add certificate extensions support (x509v3)
* Documentation (of existing functions + Manual)
cert_ASN.y cert_asn1.c cert_der.c gnutls_datum.c auth_rsa.c \
gnutls_gcry.c ext_dnsname.c gnutls_pk.c gnutls_cert.c cert_verify.c\
gnutls_global.c gnutls_privkey.c gnutls_constate.c gnutls_anon_cred.c \
- gnutls_sig_check.c pkix_asn1_tab.c pkcs1_asn1_tab.c
+ gnutls_sig_check.c pkix_asn1_tab.c pkcs1_asn1_tab.c
+
libgnutls_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
pkix_asn1_tab.c: pkix.asn
#endif
-
-
-
-
-
-
-
-
-
-
-
-
+void _gnutls_int2str(int k, char* data);
-#define MAX_DN 10*1024
+#define MAX_DN_ELEM 1024
/* This function checks if 'certs' issuer is 'issuer_cert'.
- * This does a straight compare of the DER rdnSequence.
+ * This does a compare of every element of the rdnSequence
*/
static
int compare_dn(gnutls_cert * cert, gnutls_cert * issuer_cert)
{
- node_asn *c2;
+ node_asn *c2, *c3;
int result, len;
int issuer_len;
- opaque issuer_dn[MAX_DN];
- opaque dn[MAX_DN];
+ int i, ok, finish;
+ opaque issuer_dn[MAX_DN_ELEM];
+ opaque issuer_own_dn[MAX_DN_ELEM];
-fprintf(stderr, "XXX: %s\nIII: %s\n", cert->issuer_info.common_name, issuer_cert->cert_info.common_name);
+fprintf(stderr, "XXX: %s - III: %s\n", cert->issuer_info.common_name, issuer_cert->issuer_info.common_name);
+fprintf(stderr, "XXX: %s - III: %s\n", cert->cert_info.common_name, issuer_cert->cert_info.common_name);
/* get the issuer of 'cert'
*/
if (asn1_create_structure(_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2, "certificate2") != ASN_OK) {
return GNUTLS_E_ASN1_PARSING_ERROR;
}
- issuer_len = sizeof(issuer_dn) - 1;
- if ((result =
- asn1_read_value(c2, "certificate2.tbsCertificate.issuer.rdnSequence", issuer_dn, &issuer_len)) < 0) {
- gnutls_assert();
- asn1_delete_structure(c2);
- return GNUTLS_E_ASN1_PARSING_ERROR;
- }
- asn1_delete_structure(c2);
/* get the 'subject' info of 'issuer_cert'
*/
- if (asn1_create_structure(_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2, "certificate2") != ASN_OK) {
+ if (asn1_create_structure(_gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c3, "certificate2") != ASN_OK) {
gnutls_assert();
+ asn1_delete_structure(c2);
return GNUTLS_E_ASN1_ERROR;
}
- result = asn1_get_der(c2, issuer_cert->raw.data, issuer_cert->raw.size);
+ result = asn1_get_der(c3, issuer_cert->raw.data, issuer_cert->raw.size);
if (result != ASN_OK) {
/* couldn't decode DER */
gnutls_assert();
asn1_delete_structure(c2);
return GNUTLS_E_ASN1_PARSING_ERROR;
}
+
+ i=1;
+ ok=finish=0;
+ for (;;) {
+ char tmpstr[512];
+ char intstr[4];
+
+ strcpy( tmpstr, "certificate2.tbsCertificate.issuer.rdnSequence");
+ _gnutls_int2str( i, intstr);
+ strcat( tmpstr, intstr);
+
+ issuer_len = sizeof(issuer_dn) - 1;
+ if ((result =
+ asn1_read_value(c2, tmpstr, issuer_dn, &issuer_len)) != ASN_OK) {
+ if (result!=ASN_ELEMENT_NOT_FOUND) {
+ gnutls_assert();
+ ok = 1;
+ break;
+ }
+ finish = 1;
+ }
- len = sizeof(dn) - 1;
- if ((result =
- asn1_read_value(c2, "certificate2.tbsCertificate.subject.rdnSequence", dn, &len)) < 0) {
- gnutls_assert();
- asn1_delete_structure(c2);
- return GNUTLS_E_ASN1_PARSING_ERROR;
+ len = sizeof(issuer_own_dn) - 1;
+ if ((result =
+ asn1_read_value(c3, tmpstr, issuer_own_dn, &len)) != ASN_OK) {
+ if (result!=ASN_ELEMENT_NOT_FOUND) {
+ gnutls_assert();
+ ok = 1;
+ break;
+ }
+ }
+
+ if (finish!=0 && result==ASN_ELEMENT_NOT_FOUND)
+ break; /* finished comparing */
+
+ if (memcmp(issuer_own_dn, issuer_dn, GMAX(len, issuer_len)) != 0) {
+ gnutls_assert();
+ ok = 1;
+ break;
+ }
+
+ i++;
+ if (i>999) {
+ gnutls_assert();
+ ok=1;
+ break;
+ }
}
+
asn1_delete_structure(c2);
+ asn1_delete_structure(c3);
-fprintf(stderr, "len: %d\nisslen: %d\n", len,issuer_len);
-
- if (memcmp(dn, issuer_dn, GMAX(len, issuer_len)) == 0)
- return 0;
-
+ if (ok==0) return 0;
+
gnutls_assert();
return GNUTLS_E_UNKNOWN_ERROR; /* do not match */
gnutls_assert();
return GNUTLS_CERT_NOT_TRUSTED;
}
-fprintf(stderr, "XXXissuer: %d\n", issuer->subject_pk_algorithm);
ret = gnutls_verify_signature(cert, issuer);
if (ret != GNUTLS_CERT_TRUSTED)
#include "gnutls_auth_int.h"
#include "auth_srp.h"
#include "gnutls_errors.h"
+#include "gnutls_algorithms.h"
int _gnutls_srp_recv_params( GNUTLS_STATE state, const opaque* data, int data_size) {
uint8 len;
+
+ if (_gnutls_kx_priority( state, GNUTLS_KX_SRP) < 0) {
+ /* algorithm was not allowed in this state
+ */
+ gnutls_assert();
+ return 0;
+ }
+
if (state->security_parameters.entity == GNUTLS_SERVER) {
if (data_size > 0) {
state->gnutls_key->auth_info = gnutls_calloc(1, sizeof(SRP_SERVER_AUTH_INFO));
}
} else { /* SERVER SIDE sending (g,n,s) */
/* We only send the packet if we are NOT
- * resuming
+ * resuming AND we are using SRP
*/
+ if (state->security_parameters.kx_algorithm!=GNUTLS_KX_SRP)
+ return 0; /* no data to send */
+
if (state->gnutls_internals.resumed==RESUME_FALSE)
return gen_srp_server_hello( state->gnutls_key, data);
else
int gnutls_init(GNUTLS_STATE * state, ConnectionEnd con_end);
int gnutls_deinit(GNUTLS_STATE state);
-int gnutls_bye(SOCKET cd, GNUTLS_STATE state);
-int gnutls_bye_nowait(SOCKET cd, GNUTLS_STATE state);
+int gnutls_bye(SOCKET cd, GNUTLS_STATE state, int wait);
int gnutls_handshake(SOCKET cd, GNUTLS_STATE state);
int gnutls_check_pending(GNUTLS_STATE state);
res->cert_list[res->ncerts] =
(gnutls_cert *) gnutls_realloc( res->cert_list[res->ncerts], i * sizeof(gnutls_cert));
- if (res->cert_list[res->ncerts] == NULL)
+ if (res->cert_list[res->ncerts] == NULL) {
+ gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
-
+ }
+
tmp.data = b64;
tmp.size = siz2;
if ((ret =
gnutls_datum tmp;
fd1 = fopen(cafile, "r");
- if (fd1 == NULL)
+ if (fd1 == NULL) {
+ gnutls_assert();
return GNUTLS_E_UNKNOWN_ERROR;
-
+ }
+
siz = fread(x, 1, sizeof(x), fd1);
fclose(fd1);
ptr = strstr( ptr, CERT_SEP)+1;
res->ca_list =
- (gnutls_cert *) gnutls_realloc(res->ca_list, i * sizeof(gnutls_cert));
- if (res->ca_list == NULL)
+ (gnutls_cert *) gnutls_realloc( res->ca_list, i * sizeof(gnutls_cert));
+ if (res->ca_list == NULL) {
+ gnutls_assert();
return GNUTLS_E_MEMORY_ERROR;
-
+ }
+
tmp.data = b64;
tmp.size = siz2;
if ((ret =
static int _read_rsa_params(opaque * der, int dersize, MPI ** params)
{
- opaque str[5 * 1024];
+ opaque str[MAX_X509_CERT_SIZE];
int len, result;
node_asn *spk;
/* this function will convert up to 3 digit
* numbers to characters.
*/
-static void int2str(int k, char* data) {
+void _gnutls_int2str(int k, char* data) {
if (k > 999) data[0] = 0;
else sprintf( data, "%d", k);
}
strcpy(name, root);
strcat(name, ".rdnSequence.?");
- int2str(k, counter);
+ _gnutls_int2str(k, counter);
strcat(name, counter);
len = sizeof(str) - 1;
strcpy(name2, name);
strcat(name2, ".?");
- int2str(k2, counter);
+ _gnutls_int2str(k2, counter);
strcat(name2, counter);
len = sizeof(str) - 1;
{
int result;
node_asn *c2;
- opaque str[5 * 1024];
+ opaque str[MAX_X509_CERT_SIZE];
int len = sizeof(str);
gCert->valid = 1;
result = asn1_get_der( c2, derCert.data, derCert.size);
if (result != ASN_OK) {
/* couldn't decode DER */
+#ifdef DEBUG
+ fprintf(stderr, "Decoding error %d\n", result);
+#endif
gnutls_assert();
return GNUTLS_E_ASN1_PARSING_ERROR;
}
* currently not supported
*/
gnutls_assert();
+fprintf(stderr, "ALGORITHM: %s\n", str);
+return GNUTLS_E_UNIMPLEMENTED_FEATURE;
gCert->subject_pk_algorithm = GNUTLS_PK_UNKNOWN;
gCert->params = NULL;
}
len = sizeof( gCert->signature);
+
result =
asn1_read_value
(c2, "certificate2.signature",
gCert->signature, &len);
+
if ((len % 8) !=0) {
gnutls_assert();
asn1_delete_structure(c2);
return GNUTLS_E_UNIMPLEMENTED_FEATURE;
}
+ len /= 8; /* convert to bytes */
gCert->signature_size = len;
gnutls_DN cert_info;
gnutls_DN issuer_info;
- opaque signature[MAX_HASH_SIZE];
+ opaque signature[1024];
int signature_size;
time_t expiration_time;
#define HARD_DEBUG
#define BUFFERS_DEBUG
#define RECORD_DEBUG
-#define HANDSHAKE_DEBUG*/
+#define HANDSHAKE_DEBUG
#define DEBUG
-
+*/
#define SOCKET int
#define LIST ...
#define TLS_MASTER_SIZE 48
#define MAX_HASH_SIZE 20
+#define MAX_X509_CERT_SIZE 10*1024
+
#define MAX_DNSNAME_SIZE 256
/* the default for TCP */
*/
int _gnutls_pkcs1key2gnutlsKey(gnutls_private_key * pkey, gnutls_datum cert) {
int result;
- opaque str[5*1024];
+ opaque str[MAX_X509_CERT_SIZE];
int len = sizeof(str);
node_asn *pkcs_asn;
* gnutls_bye - This function terminates the current TLS/SSL connection.
* @cd: is a connection descriptor.
* @state: is a &GNUTLS_STATE structure.
+ * @wait: is an integer
*
* Terminates the current TLS/SSL connection. If the return value is 0
* you may continue using the TCP connection. The connection should
* have been initiated using gnutls_handshake() or similar function.
+ * If 'wait' is non-zero then we will not wait for the other peer to
+ * close the TLS connection.
**/
-int gnutls_bye(SOCKET cd, GNUTLS_STATE state)
+int gnutls_bye(SOCKET cd, GNUTLS_STATE state, int wait)
{
int ret;
ret = _gnutls_send_alert(cd, state, GNUTLS_WARNING, GNUTLS_CLOSE_NOTIFY);
/* receive the closure alert */
- gnutls_recv_int(cd, state, GNUTLS_ALERT, NULL, 0, 0);
-
- state->gnutls_internals.valid_connection = VALID_FALSE;
-
- return ret;
-}
-
-/**
- * gnutls_bye_nowait - This function terminates the current TLS/SSL connection.
- * @cd: is a connection descriptor.
- * @state: is a &GNUTLS_STATE structure.
- *
- * Terminates the current TLS/SSL connection. The connection should
- * have been initiated using gnutls_handshake() or similar function.
- * This function does not wait for the other peer to close the TLS
- * connection.
- **/
-int gnutls_bye_nowait(SOCKET cd, GNUTLS_STATE state)
-{
- int ret;
-
- ret = _gnutls_send_alert(cd, state, GNUTLS_WARNING, GNUTLS_CLOSE_NOTIFY);
-
- state->gnutls_internals.valid_connection = VALID_FALSE;
-
- return ret;
-}
-
-int gnutls_close_nowait(SOCKET cd, GNUTLS_STATE state)
-{
- int ret;
-
- ret = _gnutls_send_alert(cd, state, GNUTLS_WARNING, GNUTLS_CLOSE_NOTIFY);
+ if (wait==0) gnutls_recv_int(cd, state, GNUTLS_ALERT, NULL, 0, 0);
state->gnutls_internals.valid_connection = VALID_FALSE;
* not call close().
*/
if (type != GNUTLS_ALERT)
- gnutls_close_nowait(cd, state);
+ gnutls_bye(cd, state, 1);
gnutls_free(tmpdata);
static gnutls_datum* _gnutls_get_tbs( gnutls_cert* cert) {
node_asn *c2;
gnutls_datum * ret;
-opaque str[10*1024];
+opaque str[MAX_X509_CERT_SIZE];
int result, len;
- if (asn1_create_structure( _gnutls_get_pkix(), "Certificate", &c2, "certificate")!=ASN_OK) {
+ if (asn1_create_structure( _gnutls_get_pkix(), "PKIX1Implicit88.Certificate", &c2, "certificate")!=ASN_OK) {
gnutls_assert();
return NULL;
}
result =
asn1_read_value( c2, "certificate.tbsCertificate", str, &len);
if (result != ASN_OK) {
+#ifdef DEBUG
+ fprintf(stderr, "ASN.1 failure number %d\n", result);
+#endif
gnutls_assert();
asn1_delete_structure(c2);
return NULL;
.deps
.libs
crypt
+asn1c
CertificateExample
\ No newline at end of file
main(int argc,char *argv[])
{
int result;
- FILE* tmp;
+ char* outfile;
- if(argc!=3) {
+ if(argc<2||argc>3) {
fprintf(stderr, "Usage: %s: input.asn output.c\n", argv[0]);
exit(1);
}
- result=asn1_parser_asn1_file_c( argv[1], argv[2]);
+ if (argc==3) outfile=argv[2];
+ else outfile=NULL;
+
+ result=asn1_parser_asn1_file_c( argv[1], outfile);
if(result==ASN_SYNTAX_ERROR){
printf("PARSE ERROR\n");
+++ /dev/null
------BEGIN CERTIFICATE-----
-MIIC2jCCAkOgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBmDELMAkGA1UEBhMCR1Ix
-DzANBgNVBAgTBkF0dGlraTEPMA0GA1UEBxMGQXRoaW5hMRcwFQYDVQQKEw5HTlVU
-TFMgVEVTVCBDQTEWMBQGA1UECxMNR05VVExTIERFVkVMLjEXMBUGA1UEAxMOR05V
-VExTIFRFU1QgQ0ExHTAbBgkqhkiG9w0BCQEWDm5tYXZAaGVsbHVnLmdyMB4XDTAx
-MDcyMDA3MTMyMFoXDTExMDcxODA3MTMyMFowgZgxCzAJBgNVBAYTAkdSMQ8wDQYD
-VQQIEwZBdHRpa2kxDzANBgNVBAcTBkF0aGluYTEXMBUGA1UEChMOR05VVExTIFRF
-U1QgQ0ExFjAUBgNVBAsTDUdOVVRMUyBERVZFTC4xFzAVBgNVBAMTDkdOVVRMUyBU
-RVNUIENBMR0wGwYJKoZIhvcNAQkBFg5ubWF2QGhlbGx1Zy5ncjCBnzANBgkqhkiG
-9w0BAQEFAAOBjQAwgYkCgYEAu3HbtQcFB+lQ/2OPEd14LKLRh3OzTNWZsem2rj6x
-oHTuMaIWGuzgIrJAF92wfx5+qcNJ1ZttbfhHR84dbR8wISxeoTN8jA2vy6w6qsfk
-/kuiZQb7NZML1l2tW+PzESnSxBuJSywoM6nu3Q17UeoZ4l2qgdY90iDI0lxh/0JK
-Oi0CAwEAAaMyMDAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUhJDoDTbwcum9
-BaWIOdcRxlpWRbwwDQYJKoZIhvcNAQEEBQADgYEAcDd/j9F8F0AOPu1LnsS1DquV
-7LNRApEj5OTw6tR7Xih9S8eDY2wzMi9szEykEIQ0qxOamA6V443xq4qDoturX1mg
-E60rHVHNRmy9qcqvMKn7bt+11fgXE4Ya4do+hcBMwjuI4wmXDD160mFiiMHaVmUx
-fy3Pa7F8RfUIMieurAU=
------END CERTIFICATE-----
#define RESUME
#define MAX(X,Y) (X >= Y ? X : Y);
-#define CAFILE "ca.pem"
+#define CAFILE "x509/ca.pem"
#define CRLFILE NULL
#define PRINTX(x,y) if (y[0]!=0) printf(" - %s %s\n", x, y)
print_info( state);
printf("- Disconnecting\n");
- gnutls_bye(sd, state);
+ gnutls_bye(sd, state, 0);
shutdown( sd, SHUT_WR);
close(sd);
gnutls_deinit( state);
if (FD_ISSET(fileno(stdin), &rset)) {
if( fgets(buffer, MAX_BUF, stdin) == NULL) {
- gnutls_bye(sd, state);
+ gnutls_bye(sd, state, 0);
user_term = 1;
continue;
}
printf("- Sent: %d bytes\n", strlen(buffer));
}
}
- if (user_term!=0) gnutls_bye(sd, state);
+ if (user_term!=0) gnutls_bye(sd, state, 0);
shutdown( sd, SHUT_RDWR); /* no more receptions */
close(sd);
PKCS-1 {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-1(1) modules(0) pkcs-1(1)}
--- $Revision$
-
--- This module has been checked for conformance with the ASN.1
--- standard by the OSS ASN.1 Tools
-
DEFINITIONS EXPLICIT TAGS ::=
BEGIN
coefficient INTEGER -- ti
}
--- for signature calculation -nmav
+-- for signature calculation
+-- added by nmav
-AlgorithmIdentifier ::= SEQUENCE {
+AlgorithmIdentifier ::= SEQUENCE {
algorithm OBJECT IDENTIFIER,
- parameters ANY DEFINED BY algorithm OPTIONAL }
+ parameters ANY DEFINED BY algorithm OPTIONAL
+}
-- contains a value of the type
-- registered for use with the
-- algorithm object identifier value
exit(1);
}
- if (gnutls_set_x509_server_key( x509_cred, CERTFILE, KEYFILE) < 0) {
- fprintf(stderr, "X509 PARSE ERROR\nDid you have key.pem and cert.pem?\n");
+ if (gnutls_set_x509_server_trust( x509_cred, CAFILE, CRLFILE) < 0) {
+ fprintf(stderr, "X509 PARSE ERROR\nDid you have ca.pem?\n");
exit(1);
}
- if (gnutls_set_x509_server_trust( x509_cred, CAFILE, CRLFILE) < 0) {
- fprintf(stderr, "X509 PARSE ERROR\nDid you have ca.pem?\n");
+ if (gnutls_set_x509_server_key( x509_cred, CERTFILE, KEYFILE) < 0) {
+ fprintf(stderr, "X509 PARSE ERROR\nDid you have key.pem and cert.pem?\n");
exit(1);
}
+
+
listen_sd = socket(AF_INET, SOCK_STREAM, 0);
ERR(listen_sd, "socket");
}
}
printf("\n");
- gnutls_bye_nowait(sd, state);
+ gnutls_bye(sd, state, 1); /* do not wait for
+ * the peer to close the connection.
+ */
close(sd);
gnutls_deinit(state);
}