mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-29 04:09:31 +03:00
even more dce
This commit is contained in:
1 parent
26766bf6f7
commit
8fa092106e
6 files changed
-1833
No files matched your search
@@ -18,7 +18,6 @@ libx509_la_LDFLAGS = -lgcrypt
|
||||
|
||||
libx509_la_SOURCES = \
|
||||
common.c common.h \
|
||||
dn.c dn.h \
|
||||
extensions.c extensions.h \
|
||||
mpi.c mpi.h \
|
||||
pkcs12.h \
|
||||
|
||||
@@ -1,545 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2003, 2004, 2005, 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
|
||||
*
|
||||
*/
|
||||
|
||||
#include <gnutls_int.h>
|
||||
#include <libtasn1.h>
|
||||
#include <gnutls_datum.h>
|
||||
#include <gnutls_global.h>
|
||||
#include <gnutls_errors.h>
|
||||
#include <gnutls_str.h>
|
||||
#include <common.h>
|
||||
#include <gnutls_num.h>
|
||||
#include <dn.h>
|
||||
|
||||
/* This file includes all the required to parse an X.509 Distriguished
|
||||
* Name (you need a parser just to read a name in the X.509 protoocols!!!)
|
||||
*/
|
||||
|
||||
/* Converts the given OID to an ldap acceptable string or
|
||||
* a dotted OID.
|
||||
*/
|
||||
static const char *
|
||||
oid2ldap_string (const char *oid)
|
||||
{
|
||||
const char *ret;
|
||||
|
||||
ret = MHD__gnutls_x509_oid2ldap_string (oid);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* else return the OID in dotted format */
|
||||
return oid;
|
||||
}
|
||||
|
||||
/* Escapes a string following the rules from RFC2253.
|
||||
*/
|
||||
static char *
|
||||
str_escape (char *str, char *buffer, unsigned int buffer_size)
|
||||
{
|
||||
int str_length, j, i;
|
||||
|
||||
if (str == NULL || buffer == NULL)
|
||||
return NULL;
|
||||
|
||||
str_length = MIN (strlen (str), buffer_size - 1);
|
||||
|
||||
for (i = j = 0; i < str_length; i++)
|
||||
{
|
||||
if (str[i] == ',' || str[i] == '+' || str[i] == '"'
|
||||
|| str[i] == '\\' || str[i] == '<' || str[i] == '>'
|
||||
|| str[i] == ';')
|
||||
buffer[j++] = '\\';
|
||||
|
||||
buffer[j++] = str[i];
|
||||
}
|
||||
|
||||
/* null terminate the string */
|
||||
buffer[j] = 0;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* Parses an X509 DN in the MHD__asn1_struct, and puts the output into
|
||||
* the string buf. The output is an LDAP encoded DN.
|
||||
*
|
||||
* MHD__asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
|
||||
* That is to point in the rndSequence.
|
||||
*/
|
||||
int
|
||||
MHD__gnutls_x509_parse_dn (ASN1_TYPE MHD__asn1_struct,
|
||||
const char *MHD__asn1_rdn_name, char *buf,
|
||||
size_t * sizeof_buf)
|
||||
{
|
||||
MHD_gtls_string out_str;
|
||||
int k2, k1, result;
|
||||
char tmpbuffer1[MAX_NAME_SIZE];
|
||||
char tmpbuffer2[MAX_NAME_SIZE];
|
||||
char tmpbuffer3[MAX_NAME_SIZE];
|
||||
opaque value[MAX_STRING_LEN], *value2 = NULL;
|
||||
char *escaped = NULL;
|
||||
const char *ldap_desc;
|
||||
char oid[128];
|
||||
int len, printable;
|
||||
char *string = NULL;
|
||||
size_t sizeof_string, sizeof_escaped;
|
||||
|
||||
if (sizeof_buf == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_INVALID_REQUEST;
|
||||
}
|
||||
|
||||
if (*sizeof_buf > 0 && buf)
|
||||
buf[0] = 0;
|
||||
else
|
||||
*sizeof_buf = 0;
|
||||
|
||||
MHD_gtls_string_init (&out_str, MHD_gnutls_malloc, MHD_gnutls_realloc,
|
||||
MHD_gnutls_free);
|
||||
|
||||
k1 = 0;
|
||||
do
|
||||
{
|
||||
|
||||
k1++;
|
||||
/* create a string like "tbsCertList.issuer.rdnSequence.?1"
|
||||
*/
|
||||
if (MHD__asn1_rdn_name[0] != 0)
|
||||
snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u",
|
||||
MHD__asn1_rdn_name, k1);
|
||||
else
|
||||
snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
|
||||
|
||||
len = sizeof (value) - 1;
|
||||
result =
|
||||
MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer1, value, &len);
|
||||
|
||||
if (result == ASN1_ELEMENT_NOT_FOUND)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (result != ASN1_VALUE_NOT_FOUND)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
k2 = 0;
|
||||
|
||||
do
|
||||
{ /* Move to the attibute type and values
|
||||
*/
|
||||
k2++;
|
||||
|
||||
if (tmpbuffer1[0] != 0)
|
||||
snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
|
||||
k2);
|
||||
else
|
||||
snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
|
||||
|
||||
/* Try to read the RelativeDistinguishedName attributes.
|
||||
*/
|
||||
|
||||
len = sizeof (value) - 1;
|
||||
result =
|
||||
MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer2, value, &len);
|
||||
|
||||
if (result == ASN1_ELEMENT_NOT_FOUND)
|
||||
break;
|
||||
if (result != ASN1_VALUE_NOT_FOUND)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Read the OID
|
||||
*/
|
||||
MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
|
||||
MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
|
||||
|
||||
len = sizeof (oid) - 1;
|
||||
result =
|
||||
MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, oid, &len);
|
||||
|
||||
if (result == ASN1_ELEMENT_NOT_FOUND)
|
||||
break;
|
||||
else if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Read the Value
|
||||
*/
|
||||
MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
|
||||
MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
|
||||
|
||||
len = 0;
|
||||
result =
|
||||
MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, NULL, &len);
|
||||
|
||||
value2 = MHD_gnutls_malloc (len);
|
||||
if (value2 == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = GNUTLS_E_MEMORY_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result =
|
||||
MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, value2, &len);
|
||||
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
#define STR_APPEND(y) if ((result=MHD_gtls_string_append_str( &out_str, y)) < 0) { \
|
||||
MHD_gnutls_assert(); \
|
||||
goto cleanup; \
|
||||
}
|
||||
/* The encodings of adjoining RelativeDistinguishedNames are separated
|
||||
* by a comma character (',' ASCII 44).
|
||||
*/
|
||||
|
||||
/* Where there is a multi-valued RDN, the outputs from adjoining
|
||||
* AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
|
||||
* character.
|
||||
*/
|
||||
if (k1 != 1)
|
||||
{ /* the first time do not append a comma */
|
||||
if (k2 != 1)
|
||||
{ /* adjoining multi-value RDN */
|
||||
STR_APPEND ("+");
|
||||
}
|
||||
else
|
||||
{
|
||||
STR_APPEND (",");
|
||||
}
|
||||
}
|
||||
|
||||
ldap_desc = oid2ldap_string (oid);
|
||||
printable = MHD__gnutls_x509_oid_data_printable (oid);
|
||||
|
||||
sizeof_escaped = 2 * len + 1;
|
||||
|
||||
escaped = MHD_gnutls_malloc (sizeof_escaped);
|
||||
if (escaped == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = GNUTLS_E_MEMORY_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
sizeof_string = 2 * len + 2; /* in case it is not printable */
|
||||
|
||||
string = MHD_gnutls_malloc (sizeof_string);
|
||||
if (string == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = GNUTLS_E_MEMORY_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
STR_APPEND (ldap_desc);
|
||||
STR_APPEND ("=");
|
||||
result = 0;
|
||||
|
||||
if (printable)
|
||||
result =
|
||||
MHD__gnutls_x509_oid_data2string (oid,
|
||||
value2, len,
|
||||
string, &sizeof_string);
|
||||
|
||||
if (!printable || result < 0)
|
||||
result =
|
||||
MHD__gnutls_x509_data2hex ((const unsigned char *) value2, len,
|
||||
(unsigned char *) string,
|
||||
&sizeof_string);
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
MHD__gnutls_x509_log
|
||||
("Found OID: '%s' with value '%s'\n",
|
||||
oid, MHD_gtls_bin2hex (value2, len, escaped,
|
||||
sizeof_escaped));
|
||||
goto cleanup;
|
||||
}
|
||||
STR_APPEND (str_escape (string, escaped, sizeof_escaped));
|
||||
MHD_gnutls_free (string);
|
||||
string = NULL;
|
||||
|
||||
MHD_gnutls_free (escaped);
|
||||
escaped = NULL;
|
||||
MHD_gnutls_free (value2);
|
||||
value2 = NULL;
|
||||
|
||||
}
|
||||
while (1);
|
||||
|
||||
}
|
||||
while (1);
|
||||
|
||||
if (out_str.length >= (unsigned int) *sizeof_buf)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
*sizeof_buf = out_str.length + 1;
|
||||
result = GNUTLS_E_SHORT_MEMORY_BUFFER;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (buf)
|
||||
{
|
||||
memcpy (buf, out_str.data, out_str.length);
|
||||
buf[out_str.length] = 0;
|
||||
}
|
||||
*sizeof_buf = out_str.length;
|
||||
|
||||
result = 0;
|
||||
|
||||
cleanup:
|
||||
MHD_gnutls_free (value2);
|
||||
MHD_gnutls_free (string);
|
||||
MHD_gnutls_free (escaped);
|
||||
MHD_gtls_string_clear (&out_str);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Parses an X509 DN in the MHD__asn1_struct, and searches for the
|
||||
* given OID in the DN.
|
||||
*
|
||||
* If raw_flag == 0, the output will be encoded in the LDAP way. (#hex for non printable)
|
||||
* Otherwise the raw DER data are returned.
|
||||
*
|
||||
* MHD__asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
|
||||
* That is to point in the rndSequence.
|
||||
*
|
||||
* indx specifies which OID to return. Ie 0 means return the first specified
|
||||
* OID found, 1 the second etc.
|
||||
*/
|
||||
int
|
||||
MHD__gnutls_x509_parse_dn_oid (ASN1_TYPE MHD__asn1_struct,
|
||||
const char *MHD__asn1_rdn_name,
|
||||
const char *given_oid, int indx,
|
||||
unsigned int raw_flag,
|
||||
void *buf, size_t * sizeof_buf)
|
||||
{
|
||||
int k2, k1, result;
|
||||
char tmpbuffer1[MAX_NAME_SIZE];
|
||||
char tmpbuffer2[MAX_NAME_SIZE];
|
||||
char tmpbuffer3[MAX_NAME_SIZE];
|
||||
opaque value[256];
|
||||
char oid[128];
|
||||
int len, printable;
|
||||
int i = 0;
|
||||
char *cbuf = buf;
|
||||
|
||||
if (cbuf == NULL)
|
||||
*sizeof_buf = 0;
|
||||
else
|
||||
cbuf[0] = 0;
|
||||
|
||||
k1 = 0;
|
||||
do
|
||||
{
|
||||
|
||||
k1++;
|
||||
/* create a string like "tbsCertList.issuer.rdnSequence.?1"
|
||||
*/
|
||||
if (MHD__asn1_rdn_name[0] != 0)
|
||||
snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u",
|
||||
MHD__asn1_rdn_name, k1);
|
||||
else
|
||||
snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
|
||||
|
||||
len = sizeof (value) - 1;
|
||||
result =
|
||||
MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer1, value, &len);
|
||||
|
||||
if (result == ASN1_ELEMENT_NOT_FOUND)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
break;
|
||||
}
|
||||
|
||||
if (result != ASN1_VALUE_NOT_FOUND)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
k2 = 0;
|
||||
|
||||
do
|
||||
{ /* Move to the attibute type and values
|
||||
*/
|
||||
k2++;
|
||||
|
||||
if (tmpbuffer1[0] != 0)
|
||||
snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
|
||||
k2);
|
||||
else
|
||||
snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
|
||||
|
||||
/* Try to read the RelativeDistinguishedName attributes.
|
||||
*/
|
||||
|
||||
len = sizeof (value) - 1;
|
||||
result =
|
||||
MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer2, value, &len);
|
||||
|
||||
if (result == ASN1_ELEMENT_NOT_FOUND)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (result != ASN1_VALUE_NOT_FOUND)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Read the OID
|
||||
*/
|
||||
MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
|
||||
MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
|
||||
|
||||
len = sizeof (oid) - 1;
|
||||
result =
|
||||
MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, oid, &len);
|
||||
|
||||
if (result == ASN1_ELEMENT_NOT_FOUND)
|
||||
break;
|
||||
else if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (strcmp (oid, given_oid) == 0 && indx == i++)
|
||||
{ /* Found the OID */
|
||||
|
||||
/* Read the Value
|
||||
*/
|
||||
MHD_gtls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
|
||||
MHD_gtls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
|
||||
|
||||
len = *sizeof_buf;
|
||||
result =
|
||||
MHD__asn1_read_value (MHD__asn1_struct, tmpbuffer3, buf,
|
||||
&len);
|
||||
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
if (result == ASN1_MEM_ERROR)
|
||||
*sizeof_buf = len;
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (raw_flag != 0)
|
||||
{
|
||||
if ((unsigned) len > *sizeof_buf)
|
||||
{
|
||||
*sizeof_buf = len;
|
||||
result = GNUTLS_E_SHORT_MEMORY_BUFFER;
|
||||
goto cleanup;
|
||||
}
|
||||
*sizeof_buf = len;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
else
|
||||
{ /* parse data. raw_flag == 0 */
|
||||
printable = MHD__gnutls_x509_oid_data_printable (oid);
|
||||
|
||||
if (printable == 1)
|
||||
result =
|
||||
MHD__gnutls_x509_oid_data2string (oid, buf, len,
|
||||
cbuf, sizeof_buf);
|
||||
else
|
||||
result =
|
||||
MHD__gnutls_x509_data2hex (buf, len,
|
||||
(unsigned char *) cbuf,
|
||||
sizeof_buf);
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
} /* raw_flag == 0 */
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
|
||||
}
|
||||
while (1);
|
||||
|
||||
MHD_gnutls_assert ();
|
||||
|
||||
result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
||||
|
||||
cleanup:
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compares the DER encoded part of a DN.
|
||||
*
|
||||
* FIXME: use a real DN comparison algorithm.
|
||||
*
|
||||
* Returns 1 if the DN's match and zero if they don't match. Otherwise
|
||||
* a negative value is returned to indicate error.
|
||||
*/
|
||||
int
|
||||
MHD__gnutls_x509_compare_raw_dn (const MHD_gnutls_datum_t * dn1,
|
||||
const MHD_gnutls_datum_t * dn2)
|
||||
{
|
||||
|
||||
if (dn1->size != dn2->size)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return 0;
|
||||
}
|
||||
if (memcmp (dn1->data, dn2->data, dn2->size) != 0)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return 0;
|
||||
}
|
||||
return 1; /* they match */
|
||||
}
|
||||
@@ -1,52 +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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef DN_H
|
||||
# define DN_H
|
||||
|
||||
/* Some OIDs usually found in Distinguished names
|
||||
*/
|
||||
#define OID_X520_COUNTRY_NAME "2.5.4.6"
|
||||
#define OID_X520_ORGANIZATION_NAME "2.5.4.10"
|
||||
#define OID_X520_ORGANIZATIONAL_UNIT_NAME "2.5.4.11"
|
||||
#define OID_X520_COMMON_NAME "2.5.4.3"
|
||||
#define OID_X520_LOCALITY_NAME "2.5.4.7"
|
||||
#define OID_X520_STATE_OR_PROVINCE_NAME "2.5.4.8"
|
||||
#define OID_LDAP_DC "0.9.2342.19200300.100.1.25"
|
||||
#define OID_LDAP_UID "0.9.2342.19200300.100.1.1"
|
||||
#define OID_PKCS9_EMAIL "1.2.840.113549.1.9.1"
|
||||
|
||||
int MHD__gnutls_x509_parse_dn (ASN1_TYPE MHD__asn1_struct,
|
||||
const char *MHD__asn1_rdn_name, char *buf,
|
||||
size_t * sizeof_buf);
|
||||
|
||||
int MHD__gnutls_x509_parse_dn_oid (ASN1_TYPE MHD__asn1_struct,
|
||||
const char *MHD__asn1_rdn_name,
|
||||
const char *oid, int indx,
|
||||
unsigned int raw_flag, void *buf,
|
||||
size_t * sizeof_buf);
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <gnutls_x509.h>
|
||||
#include <x509_b64.h>
|
||||
#include <x509.h>
|
||||
#include <dn.h>
|
||||
#include <extensions.h>
|
||||
#include <libtasn1.h>
|
||||
#include <mpi.h>
|
||||
@@ -177,148 +176,6 @@ cleanup:MHD_gnutls_free (signature);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_dn_by_oid - This function returns the Certificate's distinguished name
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
* @oid: holds an Object Identified in null terminated string
|
||||
* @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
|
||||
* @raw_flag: If non zero returns the raw DER data of the DN part.
|
||||
* @buf: a pointer where the DN part will be copied (may be null).
|
||||
* @sizeof_buf: initially holds the size of @buf
|
||||
*
|
||||
* This function will extract the part of the name of the Certificate
|
||||
* subject specified by the given OID. The output, if the raw flag is not
|
||||
* used, will be encoded as described in RFC2253. Thus a string that is
|
||||
* ASCII or UTF-8 encoded, depending on the certificate data.
|
||||
*
|
||||
* Some helper macros with popular OIDs can be found in gnutls/x509.h
|
||||
* If raw flag is zero, this function will only return known OIDs as
|
||||
* text. Other OIDs will be DER encoded, as described in RFC2253 --
|
||||
* in hex format with a '\#' prefix. You can check about known OIDs
|
||||
* using MHD_gnutls_x509_dn_oid_known().
|
||||
*
|
||||
* If @buf is null then only the size will be filled.
|
||||
*
|
||||
* Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
|
||||
* long enough, and in that case the *sizeof_buf will be updated with
|
||||
* the required size. On success 0 is returned.
|
||||
*
|
||||
**/
|
||||
int
|
||||
MHD_gnutls_x509_crt_get_dn_by_oid (MHD_gnutls_x509_crt_t cert,
|
||||
const char *oid,
|
||||
int indx,
|
||||
unsigned int raw_flag,
|
||||
void *buf, size_t * sizeof_buf)
|
||||
{
|
||||
if (cert == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_INVALID_REQUEST;
|
||||
}
|
||||
|
||||
return MHD__gnutls_x509_parse_dn_oid (cert->cert,
|
||||
"tbsCertificate.subject.rdnSequence",
|
||||
oid, indx, raw_flag, buf, sizeof_buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_signature_algorithm - This function returns the Certificate's signature algorithm
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
*
|
||||
* This function will return a value of the MHD_gnutls_sign_algorithm_t enumeration that
|
||||
* is the signature algorithm.
|
||||
*
|
||||
* Returns a negative value on error.
|
||||
*
|
||||
**/
|
||||
int
|
||||
MHD_gnutls_x509_crt_get_signature_algorithm (MHD_gnutls_x509_crt_t cert)
|
||||
{
|
||||
int result;
|
||||
MHD_gnutls_datum_t sa;
|
||||
|
||||
if (cert == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_INVALID_REQUEST;
|
||||
}
|
||||
|
||||
/* Read the signature algorithm. Note that parameters are not
|
||||
* read. They will be read from the issuer's certificate if needed.
|
||||
*/
|
||||
result =
|
||||
MHD__gnutls_x509_read_value (cert->cert, "signatureAlgorithm.algorithm",
|
||||
&sa, 0);
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return result;
|
||||
}
|
||||
|
||||
result = MHD_gtls_x509_oid2sign_algorithm ((const char *) sa.data);
|
||||
|
||||
MHD__gnutls_free_datum (&sa);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_signature - Returns the Certificate's signature
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
* @sig: a pointer where the signature part will be copied (may be null).
|
||||
* @sizeof_sig: initially holds the size of @sig
|
||||
*
|
||||
* This function will extract the signature field of a certificate.
|
||||
*
|
||||
* Returns 0 on success, and a negative value on error.
|
||||
**/
|
||||
int
|
||||
MHD_gnutls_x509_crt_get_signature (MHD_gnutls_x509_crt_t cert,
|
||||
char *sig, size_t * sizeof_sig)
|
||||
{
|
||||
int result;
|
||||
int bits, len;
|
||||
|
||||
if (cert == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_INVALID_REQUEST;
|
||||
}
|
||||
|
||||
bits = 0;
|
||||
result = MHD__asn1_read_value (cert->cert, "signature", NULL, &bits);
|
||||
if (result != ASN1_MEM_ERROR)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return MHD_gtls_asn2err (result);
|
||||
}
|
||||
|
||||
if (bits % 8 != 0)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_CERTIFICATE_ERROR;
|
||||
}
|
||||
|
||||
len = bits / 8;
|
||||
|
||||
if (*sizeof_sig < len)
|
||||
{
|
||||
*sizeof_sig = bits / 8;
|
||||
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
||||
}
|
||||
|
||||
result = MHD__asn1_read_value (cert->cert, "signature", sig, &len);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return MHD_gtls_asn2err (result);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_version - This function returns the Certificate's version number
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
@@ -399,50 +256,6 @@ MHD_gnutls_x509_crt_get_expiration_time (MHD_gnutls_x509_crt_t cert)
|
||||
"tbsCertificate.validity.notAfter");
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_serial - This function returns the certificate's serial number
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
* @result: The place where the serial number will be copied
|
||||
* @result_size: Holds the size of the result field.
|
||||
*
|
||||
* This function will return the X.509 certificate's serial number.
|
||||
* This is obtained by the X509 Certificate serialNumber
|
||||
* field. Serial is not always a 32 or 64bit number. Some CAs use
|
||||
* large serial numbers, thus it may be wise to handle it as something
|
||||
* opaque.
|
||||
*
|
||||
* Returns 0 on success and a negative value in case of an error.
|
||||
*
|
||||
**/
|
||||
int
|
||||
MHD_gnutls_x509_crt_get_serial (MHD_gnutls_x509_crt_t cert,
|
||||
void *result, size_t * result_size)
|
||||
{
|
||||
int ret, len;
|
||||
|
||||
if (cert == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_INVALID_REQUEST;
|
||||
}
|
||||
|
||||
len = *result_size;
|
||||
ret
|
||||
=
|
||||
MHD__asn1_read_value (cert->cert, "tbsCertificate.serialNumber", result,
|
||||
&len);
|
||||
*result_size = len;
|
||||
|
||||
if (ret != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return MHD_gtls_asn2err (ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_pk_algorithm - This function returns the certificate's PublicKey algorithm
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
@@ -496,396 +309,6 @@ is_type_printable (int type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define XMPP_OID "1.3.6.1.5.5.7.8.5"
|
||||
|
||||
/* returns the type and the name on success.
|
||||
* Type is also returned as a parameter in case of an error.
|
||||
*/
|
||||
static int
|
||||
parse_general_name (ASN1_TYPE src,
|
||||
const char *src_name,
|
||||
int seq,
|
||||
void *name,
|
||||
size_t * name_size,
|
||||
unsigned int *ret_type, int othername_oid)
|
||||
{
|
||||
int len;
|
||||
char nptr[MAX_NAME_SIZE];
|
||||
int result;
|
||||
opaque choice_type[128];
|
||||
MHD_gnutls_x509_subject_alt_name_t type;
|
||||
|
||||
seq++; /* 0->1, 1->2 etc */
|
||||
|
||||
if (src_name[0] != 0)
|
||||
snprintf (nptr, sizeof (nptr), "%s.?%u", src_name, seq);
|
||||
else
|
||||
snprintf (nptr, sizeof (nptr), "?%u", seq);
|
||||
|
||||
len = sizeof (choice_type);
|
||||
result = MHD__asn1_read_value (src, nptr, choice_type, &len);
|
||||
|
||||
if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
|
||||
{
|
||||
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return MHD_gtls_asn2err (result);
|
||||
}
|
||||
|
||||
type = MHD__gnutls_x509_san_find_type ((char *) choice_type);
|
||||
if (type == (MHD_gnutls_x509_subject_alt_name_t) - 1)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_X509_UNKNOWN_SAN;
|
||||
}
|
||||
|
||||
if (ret_type)
|
||||
*ret_type = type;
|
||||
|
||||
if (type == GNUTLS_SAN_OTHERNAME)
|
||||
{
|
||||
if (othername_oid)
|
||||
MHD_gtls_str_cat (nptr, sizeof (nptr), ".otherName.type-id");
|
||||
else
|
||||
MHD_gtls_str_cat (nptr, sizeof (nptr), ".otherName.value");
|
||||
|
||||
len = *name_size;
|
||||
result = MHD__asn1_read_value (src, nptr, name, &len);
|
||||
*name_size = len;
|
||||
|
||||
if (result == ASN1_MEM_ERROR)
|
||||
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
||||
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return MHD_gtls_asn2err (result);
|
||||
}
|
||||
|
||||
if (othername_oid)
|
||||
{
|
||||
if (len > strlen (XMPP_OID) && strcmp (name, XMPP_OID) == 0)
|
||||
type = GNUTLS_SAN_OTHERNAME_XMPP;
|
||||
}
|
||||
else
|
||||
{
|
||||
char oid[42];
|
||||
|
||||
if (src_name[0] != 0)
|
||||
snprintf (nptr, sizeof (nptr), "%s.?%u.otherName.type-id",
|
||||
src_name, seq);
|
||||
else
|
||||
snprintf (nptr, sizeof (nptr), "?%u.otherName.type-id", seq);
|
||||
|
||||
len = sizeof (oid);
|
||||
result = MHD__asn1_read_value (src, nptr, oid, &len);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return MHD_gtls_asn2err (result);
|
||||
}
|
||||
|
||||
if (len > strlen (XMPP_OID) && strcmp (oid, XMPP_OID) == 0)
|
||||
{
|
||||
ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
|
||||
|
||||
result =
|
||||
MHD__asn1_create_element (MHD__gnutls_get_pkix (),
|
||||
"PKIX1.XmppAddr", &c2);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return MHD_gtls_asn2err (result);
|
||||
}
|
||||
|
||||
result = MHD__asn1_der_decoding (&c2, name, *name_size, NULL);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
MHD__asn1_delete_structure (&c2);
|
||||
return MHD_gtls_asn2err (result);
|
||||
}
|
||||
|
||||
result = MHD__asn1_read_value (c2, "", name, &len);
|
||||
*name_size = len;
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
MHD__asn1_delete_structure (&c2);
|
||||
return MHD_gtls_asn2err (result);
|
||||
}
|
||||
MHD__asn1_delete_structure (&c2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == GNUTLS_SAN_DN)
|
||||
{
|
||||
MHD_gtls_str_cat (nptr, sizeof (nptr), ".directoryName");
|
||||
result = MHD__gnutls_x509_parse_dn (src, nptr, name, name_size);
|
||||
if (result < 0)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else if (othername_oid)
|
||||
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
||||
else
|
||||
{
|
||||
size_t orig_name_size = *name_size;
|
||||
|
||||
MHD_gtls_str_cat (nptr, sizeof (nptr), ".");
|
||||
MHD_gtls_str_cat (nptr, sizeof (nptr), (const char *) choice_type);
|
||||
|
||||
len = *name_size;
|
||||
result = MHD__asn1_read_value (src, nptr, name, &len);
|
||||
*name_size = len;
|
||||
|
||||
if (result == ASN1_MEM_ERROR)
|
||||
{
|
||||
if (is_type_printable (type))
|
||||
(*name_size)++;
|
||||
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
||||
}
|
||||
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return MHD_gtls_asn2err (result);
|
||||
}
|
||||
|
||||
if (is_type_printable (type))
|
||||
{
|
||||
|
||||
if (len + 1 > orig_name_size)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
(*name_size)++;
|
||||
return GNUTLS_E_SHORT_MEMORY_BUFFER;
|
||||
}
|
||||
|
||||
/* null terminate it */
|
||||
((char *) name)[*name_size] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static int
|
||||
get_subject_alt_name (MHD_gnutls_x509_crt_t cert,
|
||||
unsigned int seq,
|
||||
void *ret,
|
||||
size_t * ret_size,
|
||||
unsigned int *ret_type,
|
||||
unsigned int *critical, int othername_oid)
|
||||
{
|
||||
int result;
|
||||
MHD_gnutls_datum_t dnsname;
|
||||
ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
|
||||
MHD_gnutls_x509_subject_alt_name_t type;
|
||||
|
||||
if (cert == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_INVALID_REQUEST;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
memset (ret, 0, *ret_size);
|
||||
else
|
||||
*ret_size = 0;
|
||||
|
||||
if ((result =
|
||||
MHD__gnutls_x509_crt_get_extension (cert, "2.5.29.17", 0, &dnsname,
|
||||
critical)) < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (dnsname.size == 0 || dnsname.data == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
result =
|
||||
MHD__asn1_create_element (MHD__gnutls_get_pkix (), "PKIX1.SubjectAltName",
|
||||
&c2);
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
MHD__gnutls_free_datum (&dnsname);
|
||||
return MHD_gtls_asn2err (result);
|
||||
}
|
||||
|
||||
result = MHD__asn1_der_decoding (&c2, dnsname.data, dnsname.size, NULL);
|
||||
MHD__gnutls_free_datum (&dnsname);
|
||||
|
||||
if (result != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
MHD__asn1_delete_structure (&c2);
|
||||
return MHD_gtls_asn2err (result);
|
||||
}
|
||||
|
||||
result = parse_general_name (c2, "", seq, ret, ret_size, ret_type,
|
||||
othername_oid);
|
||||
|
||||
MHD__asn1_delete_structure (&c2);
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
type = result;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_subject_alt_name - Get certificate's alternative name, if any
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
* @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
|
||||
* @ret: is the place where the alternative name will be copied to
|
||||
* @ret_size: holds the size of ret.
|
||||
* @critical: will be non zero if the extension is marked as critical (may be null)
|
||||
*
|
||||
* This function will return the alternative names, contained in the
|
||||
* given certificate.
|
||||
*
|
||||
* This is specified in X509v3 Certificate Extensions. GNUTLS will
|
||||
* return the Alternative name (2.5.29.17), or a negative error code.
|
||||
*
|
||||
* When the SAN type is otherName, it will extract the data in the
|
||||
* otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
|
||||
* You may use MHD_gnutls_x509_crt_get_subject_alt_othername_oid() to get
|
||||
* the corresponding OID and the "virtual" SAN types (e.g.,
|
||||
* %GNUTLS_SAN_OTHERNAME_XMPP).
|
||||
*
|
||||
* If an otherName OID is known, the data will be decoded. Otherwise
|
||||
* the returned data will be DER encoded, and you will have to decode
|
||||
* it yourself. Currently, only the RFC 3920 id-on-xmppAddr SAN is
|
||||
* recognized.
|
||||
*
|
||||
* Returns the alternative subject name type on success. The type is
|
||||
* one of the enumerated MHD_gnutls_x509_subject_alt_name_t. It will
|
||||
* return %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large
|
||||
* enough to hold the value. In that case @ret_size will be updated
|
||||
* with the required size. If the certificate does not have an
|
||||
* Alternative name with the specified sequence number then
|
||||
* %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
|
||||
*
|
||||
**/
|
||||
int
|
||||
MHD_gnutls_x509_crt_get_subject_alt_name (MHD_gnutls_x509_crt_t cert,
|
||||
unsigned int seq,
|
||||
void *ret,
|
||||
size_t * ret_size,
|
||||
unsigned int *critical)
|
||||
{
|
||||
return get_subject_alt_name (cert, seq, ret, ret_size, NULL, critical, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_basic_constraints - This function returns the certificate basic constraints
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
* @critical: will be non zero if the extension is marked as critical
|
||||
* @ca: pointer to output integer indicating CA status, may be NULL,
|
||||
* value is 1 if the certificate CA flag is set, 0 otherwise.
|
||||
* @pathlen: pointer to output integer indicating path length (may be
|
||||
* NULL), non-negative values indicate a present pathLenConstraint
|
||||
* field and the actual value, -1 indicate that the field is absent.
|
||||
*
|
||||
* This function will read the certificate's basic constraints, and
|
||||
* return the certificates CA status. It reads the basicConstraints
|
||||
* X.509 extension (2.5.29.19).
|
||||
*
|
||||
* Return value: If the certificate is a CA a positive value will be
|
||||
* returned, or zero if the certificate does not have CA flag set. A
|
||||
* negative value may be returned in case of errors. If the
|
||||
* certificate does not contain the basicConstraints extension
|
||||
* GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
|
||||
**/
|
||||
static int
|
||||
MHD_gnutls_x509_crt_get_basic_constraints (MHD_gnutls_x509_crt_t cert,
|
||||
unsigned int *critical,
|
||||
int *ca, int *pathlen)
|
||||
{
|
||||
int result;
|
||||
MHD_gnutls_datum_t basicConstraints;
|
||||
int tmp_ca;
|
||||
|
||||
if (cert == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_INVALID_REQUEST;
|
||||
}
|
||||
|
||||
if ((result = MHD__gnutls_x509_crt_get_extension (cert, "2.5.29.19", 0,
|
||||
&basicConstraints,
|
||||
critical)) < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (basicConstraints.size == 0 || basicConstraints.data == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
result = MHD__gnutls_x509_ext_extract_basicConstraints (&tmp_ca, pathlen,
|
||||
basicConstraints.
|
||||
data,
|
||||
basicConstraints.
|
||||
size);
|
||||
if (ca)
|
||||
*ca = tmp_ca;
|
||||
MHD__gnutls_free_datum (&basicConstraints);
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return result;
|
||||
}
|
||||
|
||||
return tmp_ca;
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_ca_status - This function returns the certificate CA status
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
* @critical: will be non zero if the extension is marked as critical
|
||||
*
|
||||
* This function will return certificates CA status, by reading the
|
||||
* basicConstraints X.509 extension (2.5.29.19). If the certificate is
|
||||
* a CA a positive value will be returned, or zero if the certificate
|
||||
* does not have CA flag set.
|
||||
*
|
||||
* Use MHD_gnutls_x509_crt_get_basic_constraints() if you want to read the
|
||||
* pathLenConstraint field too.
|
||||
*
|
||||
* A negative value may be returned in case of parsing error.
|
||||
* If the certificate does not contain the basicConstraints extension
|
||||
* GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
|
||||
*
|
||||
**/
|
||||
int
|
||||
MHD_gnutls_x509_crt_get_ca_status (MHD_gnutls_x509_crt_t cert,
|
||||
unsigned int *critical)
|
||||
{
|
||||
int ca, pathlen;
|
||||
return MHD_gnutls_x509_crt_get_basic_constraints (cert, critical, &ca,
|
||||
&pathlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_key_usage - This function returns the certificate's key usage
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
@@ -1012,24 +435,6 @@ cleanup:MHD__asn1_delete_structure (&c2);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_raw_issuer_dn - This function returns the issuer's DN DER encoded
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
* @start: will hold the starting point of the DN
|
||||
*
|
||||
* This function will return a pointer to the DER encoded DN structure
|
||||
* and the length.
|
||||
*
|
||||
* Returns 0 on success or a negative value on error.
|
||||
*
|
||||
**/
|
||||
int
|
||||
MHD_gnutls_x509_crt_get_raw_issuer_dn (MHD_gnutls_x509_crt_t cert,
|
||||
MHD_gnutls_datum_t * start)
|
||||
{
|
||||
return MHD__gnutls_x509_crt_get_raw_dn2 (cert, "issuer", start);
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_raw_dn - This function returns the subject's DN DER encoded
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
@@ -1048,33 +453,6 @@ MHD_gnutls_x509_crt_get_raw_dn (MHD_gnutls_x509_crt_t cert,
|
||||
return MHD__gnutls_x509_crt_get_raw_dn2 (cert, "subject", start);
|
||||
}
|
||||
|
||||
static int
|
||||
get_dn (MHD_gnutls_x509_crt_t cert, const char *whom,
|
||||
MHD_gnutls_x509_dn_t * dn)
|
||||
{
|
||||
*dn = MHD__asn1_find_node (cert->cert, whom);
|
||||
if (!*dn)
|
||||
return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_get_subject: get opaque subject DN pointer
|
||||
* @cert: should contain a MHD_gnutls_x509_crt_t structure
|
||||
* @dn: output variable with pointer to opaque DN.
|
||||
*
|
||||
* Return the Certificate's Subject DN as an opaque data type. You
|
||||
* may use MHD_gnutls_x509_dn_get_rdn_ava() to decode the DN.
|
||||
*
|
||||
* Returns: Returns 0 on success, or an error code.
|
||||
**/
|
||||
int
|
||||
MHD_gnutls_x509_crt_get_subject (MHD_gnutls_x509_crt_t cert,
|
||||
MHD_gnutls_x509_dn_t * dn)
|
||||
{
|
||||
return get_dn (cert, "tbsCertificate.subject.rdnSequence", dn);
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_crt_export - This function will export the certificate
|
||||
* @cert: Holds the certificate
|
||||
|
||||
@@ -97,10 +97,6 @@ extern "C"
|
||||
MHD_gnutls_x509_crt_fmt_t format,
|
||||
void *output_data,
|
||||
size_t * output_data_size);
|
||||
int MHD_gnutls_x509_crt_get_signature_algorithm (MHD_gnutls_x509_crt_t
|
||||
cert);
|
||||
int MHD_gnutls_x509_crt_get_signature (MHD_gnutls_x509_crt_t cert,
|
||||
char *sig, size_t * sizeof_sig);
|
||||
int MHD_gnutls_x509_crt_get_version (MHD_gnutls_x509_crt_t cert);
|
||||
|
||||
#define GNUTLS_CRL_REASON_UNUSED 128
|
||||
@@ -115,16 +111,8 @@ extern "C"
|
||||
|
||||
time_t MHD_gnutls_x509_crt_get_activation_time (MHD_gnutls_x509_crt_t cert);
|
||||
time_t MHD_gnutls_x509_crt_get_expiration_time (MHD_gnutls_x509_crt_t cert);
|
||||
int MHD_gnutls_x509_crt_get_serial (MHD_gnutls_x509_crt_t cert,
|
||||
void *result, size_t * result_size);
|
||||
|
||||
int MHD_gnutls_x509_crt_get_pk_algorithm (MHD_gnutls_x509_crt_t cert,
|
||||
unsigned int *bits);
|
||||
int MHD_gnutls_x509_crt_get_subject_alt_name (MHD_gnutls_x509_crt_t cert,
|
||||
unsigned int seq,
|
||||
void *ret,
|
||||
size_t * ret_size,
|
||||
unsigned int *critical);
|
||||
int MHD_gnutls_x509_crt_get_ca_status (MHD_gnutls_x509_crt_t cert,
|
||||
unsigned int *critical);
|
||||
/* The key_usage flags are defined in gnutls.h. They are the
|
||||
@@ -213,8 +201,6 @@ extern "C"
|
||||
format, MHD_gnutls_datum_t * out);
|
||||
/* Access to internal Certificate fields.
|
||||
*/
|
||||
int MHD_gnutls_x509_crt_get_raw_issuer_dn (MHD_gnutls_x509_crt_t cert,
|
||||
MHD_gnutls_datum_t * start);
|
||||
int MHD_gnutls_x509_crt_get_raw_dn (MHD_gnutls_x509_crt_t cert,
|
||||
MHD_gnutls_datum_t * start);
|
||||
|
||||
@@ -227,8 +213,6 @@ extern "C"
|
||||
unsigned long value_tag;
|
||||
} MHD_gnutls_x509_ava_st;
|
||||
|
||||
int MHD_gnutls_x509_crt_get_subject (MHD_gnutls_x509_crt_t cert,
|
||||
MHD_gnutls_x509_dn_t * dn);
|
||||
struct MHD_gnutls_pkcs7_int;
|
||||
typedef struct MHD_gnutls_pkcs7_int *MHD_gnutls_pkcs7_t;
|
||||
|
||||
@@ -325,38 +309,9 @@ extern "C"
|
||||
|
||||
int MHD_gnutls_x509_privkey_init (MHD_gnutls_x509_privkey_t * key);
|
||||
void MHD_gnutls_x509_privkey_deinit (MHD_gnutls_x509_privkey_t key);
|
||||
int MHD_gnutls_x509_privkey_cpy (MHD_gnutls_x509_privkey_t dst,
|
||||
MHD_gnutls_x509_privkey_t src);
|
||||
int MHD_gnutls_x509_privkey_import (MHD_gnutls_x509_privkey_t key,
|
||||
const MHD_gnutls_datum_t * data,
|
||||
MHD_gnutls_x509_crt_fmt_t format);
|
||||
int MHD_gnutls_x509_privkey_import_pkcs8 (MHD_gnutls_x509_privkey_t key,
|
||||
const MHD_gnutls_datum_t * data,
|
||||
MHD_gnutls_x509_crt_fmt_t format,
|
||||
const char *pass,
|
||||
unsigned int flags);
|
||||
int MHD_gnutls_x509_privkey_import_rsa_raw (MHD_gnutls_x509_privkey_t key,
|
||||
const MHD_gnutls_datum_t * m,
|
||||
const MHD_gnutls_datum_t * e,
|
||||
const MHD_gnutls_datum_t * d,
|
||||
const MHD_gnutls_datum_t * p,
|
||||
const MHD_gnutls_datum_t * q,
|
||||
const MHD_gnutls_datum_t * u);
|
||||
int MHD_gnutls_x509_privkey_export_dsa_raw (MHD_gnutls_x509_privkey_t key,
|
||||
MHD_gnutls_datum_t * p,
|
||||
MHD_gnutls_datum_t * q,
|
||||
MHD_gnutls_datum_t * g,
|
||||
MHD_gnutls_datum_t * y,
|
||||
MHD_gnutls_datum_t * x);
|
||||
int MHD_gnutls_x509_privkey_import_dsa_raw (MHD_gnutls_x509_privkey_t key,
|
||||
const MHD_gnutls_datum_t * p,
|
||||
const MHD_gnutls_datum_t * q,
|
||||
const MHD_gnutls_datum_t * g,
|
||||
const MHD_gnutls_datum_t * y,
|
||||
const MHD_gnutls_datum_t * x);
|
||||
|
||||
int MHD_gnutls_x509_privkey_get_pk_algorithm (MHD_gnutls_x509_privkey_t
|
||||
key);
|
||||
int MHD_gnutls_x509_privkey_get_key_id (MHD_gnutls_x509_privkey_t key,
|
||||
unsigned int flags,
|
||||
unsigned char *output_data,
|
||||
@@ -457,27 +412,12 @@ typedef struct MHD_gtls_x509_privkey_int
|
||||
ASN1_TYPE key;
|
||||
} MHD_gnutls_x509_privkey_int;
|
||||
|
||||
int MHD_gnutls_x509_crt_get_subject_alt_name (MHD_gnutls_x509_crt_t cert,
|
||||
unsigned int seq,
|
||||
void *ret,
|
||||
size_t * ret_size,
|
||||
unsigned int *critical);
|
||||
int MHD_gnutls_x509_crt_get_dn_by_oid (MHD_gnutls_x509_crt_t cert,
|
||||
const char *oid,
|
||||
int indx,
|
||||
unsigned int raw_flag,
|
||||
void *buf, size_t * sizeof_buf);
|
||||
int MHD_gnutls_x509_crt_get_ca_status (MHD_gnutls_x509_crt_t cert,
|
||||
unsigned int *critical);
|
||||
int MHD_gnutls_x509_crt_get_pk_algorithm (MHD_gnutls_x509_crt_t cert,
|
||||
unsigned int *bits);
|
||||
|
||||
int MHD_gnutls_x509_crt_get_serial (MHD_gnutls_x509_crt_t cert,
|
||||
void *result, size_t * result_size);
|
||||
|
||||
int MHD__gnutls_x509_compare_raw_dn (const MHD_gnutls_datum_t * dn1,
|
||||
const MHD_gnutls_datum_t * dn2);
|
||||
|
||||
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);
|
||||
@@ -494,7 +434,6 @@ int MHD_gnutls_x509_crt_export (MHD_gnutls_x509_crt_t cert,
|
||||
int MHD_gnutls_x509_crt_get_key_usage (MHD_gnutls_x509_crt_t cert,
|
||||
unsigned int *key_usage,
|
||||
unsigned int *critical);
|
||||
int MHD_gnutls_x509_crt_get_signature_algorithm (MHD_gnutls_x509_crt_t cert);
|
||||
int MHD_gnutls_x509_crt_get_version (MHD_gnutls_x509_crt_t cert);
|
||||
|
||||
int MHD_gnutls_x509_privkey_init (MHD_gnutls_x509_privkey_t * key);
|
||||
@@ -507,14 +446,6 @@ int MHD_gnutls_x509_privkey_generate (MHD_gnutls_x509_privkey_t key,
|
||||
int MHD_gnutls_x509_privkey_import (MHD_gnutls_x509_privkey_t key,
|
||||
const MHD_gnutls_datum_t * data,
|
||||
MHD_gnutls_x509_crt_fmt_t format);
|
||||
int MHD_gnutls_x509_privkey_get_pk_algorithm (MHD_gnutls_x509_privkey_t key);
|
||||
int MHD_gnutls_x509_privkey_import_rsa_raw (MHD_gnutls_x509_privkey_t key,
|
||||
const MHD_gnutls_datum_t * m,
|
||||
const MHD_gnutls_datum_t * e,
|
||||
const MHD_gnutls_datum_t * d,
|
||||
const MHD_gnutls_datum_t * p,
|
||||
const MHD_gnutls_datum_t * q,
|
||||
const MHD_gnutls_datum_t * u);
|
||||
int MHD_gnutls_x509_privkey_export_rsa_raw (MHD_gnutls_x509_privkey_t key,
|
||||
MHD_gnutls_datum_t * m,
|
||||
MHD_gnutls_datum_t * e,
|
||||
|
||||
@@ -32,13 +32,9 @@
|
||||
#include <gnutls_x509.h>
|
||||
#include <x509_b64.h>
|
||||
#include <x509.h>
|
||||
#include <dn.h>
|
||||
#include <mpi.h>
|
||||
#include <extensions.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);
|
||||
|
||||
/* remove this when libgcrypt can handle the PKCS #1 coefficients from
|
||||
* rsa keys
|
||||
*/
|
||||
@@ -92,54 +88,6 @@ MHD_gnutls_x509_privkey_deinit (MHD_gnutls_x509_privkey_t key)
|
||||
MHD_gnutls_free (key);
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_privkey_cpy - This function copies a private key
|
||||
* @dst: The destination key, which should be initialized.
|
||||
* @src: The source key
|
||||
*
|
||||
* This function will copy a private key from source to destination key.
|
||||
*
|
||||
**/
|
||||
int
|
||||
MHD_gnutls_x509_privkey_cpy (MHD_gnutls_x509_privkey_t dst,
|
||||
MHD_gnutls_x509_privkey_t src)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
if (!src || !dst)
|
||||
return GNUTLS_E_INVALID_REQUEST;
|
||||
|
||||
for (i = 0; i < src->params_size; i++)
|
||||
{
|
||||
dst->params[i] = MHD__gnutls_mpi_copy (src->params[i]);
|
||||
if (dst->params[i] == NULL)
|
||||
return GNUTLS_E_MEMORY_ERROR;
|
||||
}
|
||||
|
||||
dst->params_size = src->params_size;
|
||||
dst->pk_algorithm = src->pk_algorithm;
|
||||
dst->crippled = src->crippled;
|
||||
|
||||
if (!src->crippled)
|
||||
{
|
||||
switch (dst->pk_algorithm)
|
||||
{
|
||||
case MHD_GNUTLS_PK_RSA:
|
||||
ret = MHD__gnutls_asn1_encode_rsa (&dst->key, dst->params);
|
||||
if (ret < 0)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_INVALID_REQUEST;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Converts an RSA PKCS#1 key to
|
||||
* an internal structure (MHD_gnutls_private_key)
|
||||
@@ -340,495 +288,3 @@ MHD_gnutls_x509_privkey_import (MHD_gnutls_x509_privkey_t key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define FREE_RSA_PRIVATE_PARAMS for (i=0;i<RSA_PRIVATE_PARAMS;i++) \
|
||||
MHD_gtls_mpi_release(&key->params[i])
|
||||
#define FREE_DSA_PRIVATE_PARAMS for (i=0;i<DSA_PRIVATE_PARAMS;i++) \
|
||||
MHD_gtls_mpi_release(&key->params[i])
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_privkey_import_rsa_raw - This function will import a raw RSA key
|
||||
* @key: The structure to store the parsed key
|
||||
* @m: holds the modulus
|
||||
* @e: holds the public exponent
|
||||
* @d: holds the private exponent
|
||||
* @p: holds the first prime (p)
|
||||
* @q: holds the second prime (q)
|
||||
* @u: holds the coefficient
|
||||
*
|
||||
* This function will convert the given RSA raw parameters
|
||||
* to the native MHD_gnutls_x509_privkey_t format. The output will be stored in @key.
|
||||
*
|
||||
**/
|
||||
int
|
||||
MHD_gnutls_x509_privkey_import_rsa_raw (MHD_gnutls_x509_privkey_t key,
|
||||
const MHD_gnutls_datum_t * m,
|
||||
const MHD_gnutls_datum_t * e,
|
||||
const MHD_gnutls_datum_t * d,
|
||||
const MHD_gnutls_datum_t * p,
|
||||
const MHD_gnutls_datum_t * q,
|
||||
const MHD_gnutls_datum_t * u)
|
||||
{
|
||||
int i = 0, ret;
|
||||
size_t siz = 0;
|
||||
|
||||
if (key == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_INVALID_REQUEST;
|
||||
}
|
||||
|
||||
siz = m->size;
|
||||
if (MHD_gtls_mpi_scan_nz (&key->params[0], m->data, &siz))
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
FREE_RSA_PRIVATE_PARAMS;
|
||||
return GNUTLS_E_MPI_SCAN_FAILED;
|
||||
}
|
||||
|
||||
siz = e->size;
|
||||
if (MHD_gtls_mpi_scan_nz (&key->params[1], e->data, &siz))
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
FREE_RSA_PRIVATE_PARAMS;
|
||||
return GNUTLS_E_MPI_SCAN_FAILED;
|
||||
}
|
||||
|
||||
siz = d->size;
|
||||
if (MHD_gtls_mpi_scan_nz (&key->params[2], d->data, &siz))
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
FREE_RSA_PRIVATE_PARAMS;
|
||||
return GNUTLS_E_MPI_SCAN_FAILED;
|
||||
}
|
||||
|
||||
siz = p->size;
|
||||
if (MHD_gtls_mpi_scan_nz (&key->params[3], p->data, &siz))
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
FREE_RSA_PRIVATE_PARAMS;
|
||||
return GNUTLS_E_MPI_SCAN_FAILED;
|
||||
}
|
||||
|
||||
siz = q->size;
|
||||
if (MHD_gtls_mpi_scan_nz (&key->params[4], q->data, &siz))
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
FREE_RSA_PRIVATE_PARAMS;
|
||||
return GNUTLS_E_MPI_SCAN_FAILED;
|
||||
}
|
||||
|
||||
#ifdef CALC_COEFF
|
||||
key->params[5] =
|
||||
MHD__gnutls_mpi_snew (MHD__gnutls_mpi_get_nbits (key->params[0]));
|
||||
|
||||
if (key->params[5] == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
FREE_RSA_PRIVATE_PARAMS;
|
||||
return GNUTLS_E_MEMORY_ERROR;
|
||||
}
|
||||
|
||||
MHD__gnutls_mpi_invm (key->params[5], key->params[3], key->params[4]);
|
||||
#else
|
||||
siz = u->size;
|
||||
if (MHD_gtls_mpi_scan_nz (&key->params[5], u->data, &siz))
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
FREE_RSA_PRIVATE_PARAMS;
|
||||
return GNUTLS_E_MPI_SCAN_FAILED;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!key->crippled)
|
||||
{
|
||||
ret = MHD__gnutls_asn1_encode_rsa (&key->key, key->params);
|
||||
if (ret < 0)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
FREE_RSA_PRIVATE_PARAMS;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
key->params_size = RSA_PRIVATE_PARAMS;
|
||||
key->pk_algorithm = MHD_GNUTLS_PK_RSA;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* MHD_gnutls_x509_privkey_get_pk_algorithm - This function returns the key's PublicKey algorithm
|
||||
* @key: should contain a MHD_gnutls_x509_privkey_t structure
|
||||
*
|
||||
* This function will return the public key algorithm of a private
|
||||
* key.
|
||||
*
|
||||
* Returns a member of the enum MHD_GNUTLS_PublicKeyAlgorithm enumeration on success,
|
||||
* or a negative value on error.
|
||||
*
|
||||
**/
|
||||
int
|
||||
MHD_gnutls_x509_privkey_get_pk_algorithm (MHD_gnutls_x509_privkey_t key)
|
||||
{
|
||||
if (key == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
return GNUTLS_E_INVALID_REQUEST;
|
||||
}
|
||||
|
||||
return key->pk_algorithm;
|
||||
}
|
||||
|
||||
/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
|
||||
*/
|
||||
static int
|
||||
MHD__gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params)
|
||||
{
|
||||
int result, i;
|
||||
size_t size[8], total;
|
||||
opaque *m_data, *pube_data, *prie_data;
|
||||
opaque *p1_data, *p2_data, *u_data, *exp1_data, *exp2_data;
|
||||
opaque *all_data = NULL, *p;
|
||||
mpi_t exp1 = NULL, exp2 = NULL, q1 = NULL, p1 = NULL, u = NULL;
|
||||
opaque null = '\0';
|
||||
|
||||
/* Read all the sizes */
|
||||
total = 0;
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
MHD_gtls_mpi_print_lz (NULL, &size[i], params[i]);
|
||||
total += size[i];
|
||||
}
|
||||
|
||||
/* Now generate exp1 and exp2
|
||||
*/
|
||||
exp1 = MHD__gnutls_mpi_salloc_like (params[0]); /* like modulus */
|
||||
if (exp1 == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = GNUTLS_E_MEMORY_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
exp2 = MHD__gnutls_mpi_salloc_like (params[0]);
|
||||
if (exp2 == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = GNUTLS_E_MEMORY_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
q1 = MHD__gnutls_mpi_salloc_like (params[4]);
|
||||
if (q1 == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = GNUTLS_E_MEMORY_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
p1 = MHD__gnutls_mpi_salloc_like (params[3]);
|
||||
if (p1 == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = GNUTLS_E_MEMORY_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
u = MHD__gnutls_mpi_salloc_like (params[3]);
|
||||
if (u == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = GNUTLS_E_MEMORY_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MHD__gnutls_mpi_invm (u, params[4], params[3]);
|
||||
/* inverse of q mod p */
|
||||
MHD_gtls_mpi_print_lz (NULL, &size[5], u);
|
||||
total += size[5];
|
||||
|
||||
MHD__gnutls_mpi_sub_ui (p1, params[3], 1);
|
||||
MHD__gnutls_mpi_sub_ui (q1, params[4], 1);
|
||||
|
||||
MHD__gnutls_mpi_mod (exp1, params[2], p1);
|
||||
MHD__gnutls_mpi_mod (exp2, params[2], q1);
|
||||
|
||||
/* calculate exp's size */
|
||||
MHD_gtls_mpi_print_lz (NULL, &size[6], exp1);
|
||||
total += size[6];
|
||||
|
||||
MHD_gtls_mpi_print_lz (NULL, &size[7], exp2);
|
||||
total += size[7];
|
||||
|
||||
/* Encoding phase.
|
||||
* allocate data enough to hold everything
|
||||
*/
|
||||
all_data = MHD_gnutls_secure_malloc (total);
|
||||
if (all_data == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = GNUTLS_E_MEMORY_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
p = all_data;
|
||||
m_data = p;
|
||||
p += size[0];
|
||||
pube_data = p;
|
||||
p += size[1];
|
||||
prie_data = p;
|
||||
p += size[2];
|
||||
p1_data = p;
|
||||
p += size[3];
|
||||
p2_data = p;
|
||||
p += size[4];
|
||||
u_data = p;
|
||||
p += size[5];
|
||||
exp1_data = p;
|
||||
p += size[6];
|
||||
exp2_data = p;
|
||||
|
||||
MHD_gtls_mpi_print_lz (m_data, &size[0], params[0]);
|
||||
MHD_gtls_mpi_print_lz (pube_data, &size[1], params[1]);
|
||||
MHD_gtls_mpi_print_lz (prie_data, &size[2], params[2]);
|
||||
MHD_gtls_mpi_print_lz (p1_data, &size[3], params[3]);
|
||||
MHD_gtls_mpi_print_lz (p2_data, &size[4], params[4]);
|
||||
MHD_gtls_mpi_print_lz (u_data, &size[5], u);
|
||||
MHD_gtls_mpi_print_lz (exp1_data, &size[6], exp1);
|
||||
MHD_gtls_mpi_print_lz (exp2_data, &size[7], exp2);
|
||||
|
||||
/* Ok. Now we have the data. Create the asn1 structures
|
||||
*/
|
||||
|
||||
if ((result =
|
||||
MHD__asn1_create_element (MHD__gnutls_getMHD__gnutls_asn (),
|
||||
"GNUTLS.RSAPrivateKey", c2)) != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Write PRIME
|
||||
*/
|
||||
if ((result = MHD__asn1_write_value (*c2, "modulus", m_data, size[0]))
|
||||
!= ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((result =
|
||||
MHD__asn1_write_value (*c2, "publicExponent", pube_data,
|
||||
size[1])) != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((result =
|
||||
MHD__asn1_write_value (*c2, "privateExponent", prie_data,
|
||||
size[2])) != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((result = MHD__asn1_write_value (*c2, "prime1", p1_data, size[3]))
|
||||
!= ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((result = MHD__asn1_write_value (*c2, "prime2", p2_data, size[4]))
|
||||
!= ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((result = MHD__asn1_write_value (*c2, "exponent1", exp1_data, size[6]))
|
||||
!= ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((result = MHD__asn1_write_value (*c2, "exponent2", exp2_data, size[7]))
|
||||
!= ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((result = MHD__asn1_write_value (*c2, "coefficient", u_data, size[5]))
|
||||
!= ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MHD_gtls_mpi_release (&exp1);
|
||||
MHD_gtls_mpi_release (&exp2);
|
||||
MHD_gtls_mpi_release (&q1);
|
||||
MHD_gtls_mpi_release (&p1);
|
||||
MHD_gtls_mpi_release (&u);
|
||||
MHD_gnutls_free (all_data);
|
||||
|
||||
if ((result = MHD__asn1_write_value (*c2, "otherPrimeInfos",
|
||||
NULL, 0)) != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((result =
|
||||
MHD__asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:MHD_gtls_mpi_release (&u);
|
||||
MHD_gtls_mpi_release (&exp1);
|
||||
MHD_gtls_mpi_release (&exp2);
|
||||
MHD_gtls_mpi_release (&q1);
|
||||
MHD_gtls_mpi_release (&p1);
|
||||
MHD__asn1_delete_structure (c2);
|
||||
MHD_gnutls_free (all_data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
|
||||
*/
|
||||
int
|
||||
MHD__gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params)
|
||||
{
|
||||
int result, i;
|
||||
size_t size[DSA_PRIVATE_PARAMS], total;
|
||||
opaque *p_data, *q_data, *g_data, *x_data, *y_data;
|
||||
opaque *all_data = NULL, *p;
|
||||
opaque null = '\0';
|
||||
|
||||
/* Read all the sizes */
|
||||
total = 0;
|
||||
for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
|
||||
{
|
||||
MHD_gtls_mpi_print_lz (NULL, &size[i], params[i]);
|
||||
total += size[i];
|
||||
}
|
||||
|
||||
/* Encoding phase.
|
||||
* allocate data enough to hold everything
|
||||
*/
|
||||
all_data = MHD_gnutls_secure_malloc (total);
|
||||
if (all_data == NULL)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = GNUTLS_E_MEMORY_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
p = all_data;
|
||||
p_data = p;
|
||||
p += size[0];
|
||||
q_data = p;
|
||||
p += size[1];
|
||||
g_data = p;
|
||||
p += size[2];
|
||||
y_data = p;
|
||||
p += size[3];
|
||||
x_data = p;
|
||||
|
||||
MHD_gtls_mpi_print_lz (p_data, &size[0], params[0]);
|
||||
MHD_gtls_mpi_print_lz (q_data, &size[1], params[1]);
|
||||
MHD_gtls_mpi_print_lz (g_data, &size[2], params[2]);
|
||||
MHD_gtls_mpi_print_lz (y_data, &size[3], params[3]);
|
||||
MHD_gtls_mpi_print_lz (x_data, &size[4], params[4]);
|
||||
|
||||
/* Ok. Now we have the data. Create the asn1 structures
|
||||
*/
|
||||
|
||||
if ((result =
|
||||
MHD__asn1_create_element (MHD__gnutls_getMHD__gnutls_asn (),
|
||||
"GNUTLS.DSAPrivateKey", c2)) != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Write PRIME
|
||||
*/
|
||||
if ((result =
|
||||
MHD__asn1_write_value (*c2, "p", p_data, size[0])) != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((result =
|
||||
MHD__asn1_write_value (*c2, "q", q_data, size[1])) != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((result =
|
||||
MHD__asn1_write_value (*c2, "g", g_data, size[2])) != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((result =
|
||||
MHD__asn1_write_value (*c2, "Y", y_data, size[3])) != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((result =
|
||||
MHD__asn1_write_value (*c2, "priv", x_data, size[4])) != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
MHD_gnutls_free (all_data);
|
||||
|
||||
if ((result =
|
||||
MHD__asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
|
||||
{
|
||||
MHD_gnutls_assert ();
|
||||
result = MHD_gtls_asn2err (result);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:MHD__asn1_delete_structure (c2);
|
||||
MHD_gnutls_free (all_data);
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in new issue
Block a user