if ((ret =
_gnutls_x509_cert2gnutls_cert(&peer_certificate_list
- [j], tmp)) < 0) {
+ [j], tmp, 1)) < 0) {
gnutls_assert();
CLEAR_CERTS;
gnutls_afree(peer_certificate_list);
ret =
_gnutls_x509_cert2gnutls_cert(&peer_cert,
info->
- raw_certificate_list[0]);
+ raw_certificate_list[0], 1);
break;
case GNUTLS_CRT_OPENPGP:
if (_E_gnutls_openpgp_cert2gnutls_cert==NULL) {
case GNUTLS_CRT_X509:
if ((ret =
_gnutls_x509_cert2gnutls_cert( &peer_cert,
- info->raw_certificate_list[0])) < 0) {
+ info->raw_certificate_list[0], 1)) < 0) {
gnutls_assert();
return ret;
}
case GNUTLS_CRT_X509:
if ((ret =
_gnutls_x509_cert2gnutls_cert( &peer_cert,
- info->raw_certificate_list[0])) < 0) {
+ info->raw_certificate_list[0], 1)) < 0) {
gnutls_assert();
return ret;
}
uint16 keyUsage; /* bits from X509KEY_*
*/
- int valid; /* 0 if the certificate looks good.
- */
-
int CA; /* 0 if the certificate does not belong to
* a certificate authority. 1 otherwise.
*/
if (ret2 < 0)
return ret2;
-
+ break;
+ default:
+ gnutls_assert();
+ return GNUTLS_E_INTERNAL_ERROR;
}
STATE = STATE0;
void _gnutls_string_init( gnutls_string*, ALLOC_FUNC, REALLOC_FUNC, FREE_FUNC);
void _gnutls_string_clear( gnutls_string*);
+
+/* Beware, do not clear the string, after calling this
+ * function
+ */
gnutls_datum _gnutls_string2datum( gnutls_string* str);
+
int _gnutls_string_copy_str( gnutls_string* dest, const char* src);
int _gnutls_string_append_str( gnutls_string*, const char* str);
int _gnutls_string_append_data( gnutls_string*, const void* data, size_t data_size);
if ((ret =
_gnutls_x509_cert2gnutls_cert(&peer_certificate_list[i],
info->
- raw_certificate_list[i])) <
+ raw_certificate_list[i], 0)) <
0) {
gnutls_assert();
CLEAR_CERTS;
for (i = 0; i < peer_certificate_list_size; i++) {
if ((ret =
_gnutls_x509_cert2gnutls_cert(&peer_certificate_list[i],
- cert_list[i])) < 0) {
+ cert_list[i], 0)) < 0) {
gnutls_assert();
CLEAR_CERTS_CA;
gnutls_free( peer_certificate_list);
for (i = 0; i < ca_certificate_list_size; i++) {
if ((ret =
_gnutls_x509_cert2gnutls_cert(&ca_certificate_list[i],
- CA_list[i])) < 0) {
+ CA_list[i], 0)) < 0) {
gnutls_assert();
CLEAR_CERTS_CA;
gnutls_free( peer_certificate_list);
if ((ret =
_gnutls_x509_cert2gnutls_cert(
&cert_list[0][i - 1],
- tmp)) < 0) {
+ tmp, 0)) < 0) {
gnutls_assert();
return ret;
}
if ((ret =
_gnutls_x509_cert2gnutls_cert(
&cert_list[0][i - 1],
- tmp2)) < 0) {
+ tmp2, 0)) < 0) {
gnutls_assert();
return ret;
}
if ((ret =
_gnutls_x509_cert2gnutls_cert(
&cert_list[0][i - 1],
- tmp)) < 0) {
+ tmp, 0)) < 0) {
gnutls_free(b64);
gnutls_assert();
return ret;
* (structure) that gnutls can understand and use. Actually the
* important thing on this function is that it extracts the
* certificate's (public key) parameters.
+ *
+ * The noext flag is used to complete the handshake even if the
+ * extensions found in the certificate are unsupported and critical.
+ * The critical extensions will be catched by the verification functions.
*/
-int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert)
+int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert,
+ int no_critical_ext /* if non zero do not parse X.509 extensions */)
{
int result;
ASN1_TYPE c2;
memset(gCert, 0, sizeof(gnutls_cert));
- gCert->valid = 1;
gCert->cert_type = GNUTLS_CRT_X509;
if (gnutls_set_datum(&gCert->raw, derCert.data, derCert.size) < 0) {
if ((result =
_gnutls_get_ext_type(c2,
"certificate2.tbsCertificate.extensions",
- gCert)) < 0) {
+ gCert, no_critical_ext)) < 0) {
gnutls_assert();
asn1_delete_structure(&c2);
gnutls_free_datum( &gCert->raw);
asn1_delete_structure(&c2);
-
- gCert->valid = 0; /* if we got until here
- * the certificate is valid.
- */
-
return 0;
}
#include <libtasn1.h>
int _gnutls_x509_cert_verify_peers(GNUTLS_STATE state);
-int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert);
+int _gnutls_x509_cert2gnutls_cert(gnutls_cert * gCert, gnutls_datum derCert, int noext);
#define MAX_INT_DIGITS 4
void _gnutls_int2str(unsigned int k, char *data);
}
+/*
+ * If no_critical_ext is non zero, then unsupported critical extensions
+ * do not lead into a fatal error.
+ */
static int _parse_extension(gnutls_cert * cert, char *extnID,
char *critical, char *extnValue,
- int extnValueLen)
+ int extnValueLen, int no_critical_ext)
{
if (strcmp(extnID, "2 5 29 14") == 0) { /* subject Key ID */
_gnutls_x509_log("X509_EXT: CERT[%s]: Unsupported Extension: %s, %s\n",
GET_CN(cert->raw), extnID, critical);
- if (strcmp(critical, "TRUE") == 0) {
+ if (strcmp(critical, "TRUE") == 0 && no_critical_ext == 0) {
gnutls_assert();
return GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION;
}
/* This function will attempt to parse Extensions in
* an X509v3 certificate
+ *
+ * If no_critical_ext is non zero, then unsupported critical extensions
+ * do not lead into a fatal error.
*/
-int _gnutls_get_ext_type(ASN1_TYPE rasn, char *root, gnutls_cert * cert)
+int _gnutls_get_ext_type(ASN1_TYPE rasn, char *root, gnutls_cert * cert,
+ int no_critical_ext)
{
int k, result, len;
char name[128], name2[128], counter[MAX_INT_DIGITS];
/* Handle Extension */
if ((result =
_parse_extension(cert, extnID, critical,
- extnValue, len)) < 0) {
+ extnValue, len, no_critical_ext)) < 0) {
gnutls_assert();
return result;
}
-int _gnutls_get_ext_type( ASN1_TYPE rasn, char *root, gnutls_cert *cert);
+int _gnutls_get_ext_type( ASN1_TYPE rasn, char *root, gnutls_cert *cert, int no_critical_ext);
int _gnutls_get_extension( const gnutls_datum * cert, const char* extension_id, gnutls_datum* ret);
gnutls_free_datum(&tbs);
return 0;
break;
+ default:
+ gnutls_assert();
+ gnutls_free_datum(&tbs);
+ return GNUTLS_E_INTERNAL_ERROR;
}