00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <gnutls_int.h>
00026 #include <libtasn1.h>
00027 #include <gnutls_datum.h>
00028 #include <gnutls_global.h>
00029 #include <gnutls_errors.h>
00030 #include <gnutls_str.h>
00031 #include <gnutls_x509.h>
00032 #include <gnutls_num.h>
00033 #include <x509_b64.h>
00034 #include <common.h>
00035 #include <mpi.h>
00036 #include <time.h>
00037
00038
00039
00040
00041 int
00042 MHD__gnutls_x509_export_int (ASN1_TYPE MHD__asn1_data,
00043 MHD_gnutls_x509_crt_fmt_t format,
00044 char *pem_header,
00045 unsigned char *output_data,
00046 size_t * output_data_size)
00047 {
00048 int result, len;
00049
00050 if (format == GNUTLS_X509_FMT_DER)
00051 {
00052
00053 if (output_data == NULL)
00054 *output_data_size = 0;
00055
00056 len = *output_data_size;
00057
00058 if ((result =
00059 MHD__asn1_der_coding (MHD__asn1_data, "", output_data, &len,
00060 NULL)) != ASN1_SUCCESS)
00061 {
00062 *output_data_size = len;
00063 if (result == ASN1_MEM_ERROR)
00064 {
00065 return GNUTLS_E_SHORT_MEMORY_BUFFER;
00066 }
00067 MHD_gnutls_assert ();
00068 return MHD_gtls_asn2err (result);
00069 }
00070
00071 *output_data_size = len;
00072
00073 }
00074 else
00075 {
00076 opaque *out;
00077 MHD_gnutls_datum_t tmp;
00078
00079 result = MHD__gnutls_x509_der_encode (MHD__asn1_data, "", &tmp, 0);
00080 if (result < 0)
00081 {
00082 MHD_gnutls_assert ();
00083 return result;
00084 }
00085
00086 result =
00087 MHD__gnutls_fbase64_encode (pem_header, tmp.data, tmp.size, &out);
00088
00089 MHD__gnutls_free_datum (&tmp);
00090
00091 if (result < 0)
00092 {
00093 MHD_gnutls_assert ();
00094 return result;
00095 }
00096
00097 if (result == 0)
00098 {
00099 MHD_gnutls_assert ();
00100 return GNUTLS_E_INTERNAL_ERROR;
00101 }
00102
00103 if ((unsigned) result > *output_data_size)
00104 {
00105 MHD_gnutls_assert ();
00106 MHD_gnutls_free (out);
00107 *output_data_size = result;
00108 return GNUTLS_E_SHORT_MEMORY_BUFFER;
00109 }
00110
00111 *output_data_size = result;
00112
00113 if (output_data)
00114 {
00115 memcpy (output_data, out, result);
00116
00117
00118
00119 *output_data_size = result - 1;
00120 }
00121 MHD_gnutls_free (out);
00122
00123 }
00124
00125 return 0;
00126 }
00127
00128
00129
00130
00131
00132 static int
00133 MHD__gnutls_x509_decode_octet_string (const char *string_type,
00134 const opaque * der,
00135 size_t der_size,
00136 opaque * output, size_t * output_size)
00137 {
00138 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
00139 int result, tmp_output_size;
00140 char strname[64];
00141
00142 if (string_type == NULL)
00143 MHD_gtls_str_cpy (strname, sizeof (strname), "PKIX1.pkcs-7-Data");
00144 else
00145 {
00146 MHD_gtls_str_cpy (strname, sizeof (strname), "PKIX1.");
00147 MHD_gtls_str_cat (strname, sizeof (strname), string_type);
00148 }
00149
00150 if ((result =
00151 MHD__asn1_create_element (MHD__gnutls_get_pkix (), strname,
00152 &c2)) != ASN1_SUCCESS)
00153 {
00154 MHD_gnutls_assert ();
00155 result = MHD_gtls_asn2err (result);
00156 goto cleanup;
00157 }
00158
00159 result = MHD__asn1_der_decoding (&c2, der, der_size, NULL);
00160 if (result != ASN1_SUCCESS)
00161 {
00162 MHD_gnutls_assert ();
00163 result = MHD_gtls_asn2err (result);
00164 goto cleanup;
00165 }
00166
00167 tmp_output_size = *output_size;
00168 result = MHD__asn1_read_value (c2, "", output, &tmp_output_size);
00169 *output_size = tmp_output_size;
00170
00171 if (result != ASN1_SUCCESS)
00172 {
00173 MHD_gnutls_assert ();
00174 result = MHD_gtls_asn2err (result);
00175 goto cleanup;
00176 }
00177
00178 return 0;
00179
00180 cleanup:if (c2)
00181 MHD__asn1_delete_structure (&c2);
00182
00183 return result;
00184 }
00185
00186
00187
00188
00189
00190
00191
00192 int
00193 MHD__gnutls_x509_read_value (ASN1_TYPE c,
00194 const char *root, MHD_gnutls_datum_t * ret,
00195 int flags)
00196 {
00197 int len = 0, result;
00198 size_t slen;
00199 opaque *tmp = NULL;
00200
00201 result = MHD__asn1_read_value (c, root, NULL, &len);
00202 if (result != ASN1_MEM_ERROR)
00203 {
00204 MHD_gnutls_assert ();
00205 result = MHD_gtls_asn2err (result);
00206 return result;
00207 }
00208
00209 if (flags == 2)
00210 len /= 8;
00211
00212 tmp = MHD_gnutls_malloc (len);
00213 if (tmp == NULL)
00214 {
00215 MHD_gnutls_assert ();
00216 result = GNUTLS_E_MEMORY_ERROR;
00217 goto cleanup;
00218 }
00219
00220 result = MHD__asn1_read_value (c, root, tmp, &len);
00221 if (result != ASN1_SUCCESS)
00222 {
00223 MHD_gnutls_assert ();
00224 result = MHD_gtls_asn2err (result);
00225 goto cleanup;
00226 }
00227
00228 if (flags == 2)
00229 len /= 8;
00230
00231
00232
00233
00234 if (flags == 1)
00235 {
00236 slen = len;
00237 result =
00238 MHD__gnutls_x509_decode_octet_string (NULL, tmp, slen, tmp, &slen);
00239 if (result < 0)
00240 {
00241 MHD_gnutls_assert ();
00242 goto cleanup;
00243 }
00244 len = slen;
00245 }
00246
00247 ret->data = tmp;
00248 ret->size = len;
00249
00250 return 0;
00251
00252 cleanup:MHD_gnutls_free (tmp);
00253 return result;
00254
00255 }
00256
00257
00258
00259
00260
00261 int
00262 MHD__gnutls_x509_der_encode (ASN1_TYPE src,
00263 const char *src_name, MHD_gnutls_datum_t * res,
00264 int str)
00265 {
00266 int size, result;
00267 int asize;
00268 opaque *data = NULL;
00269 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
00270
00271 size = 0;
00272 result = MHD__asn1_der_coding (src, src_name, NULL, &size, NULL);
00273 if (result != ASN1_MEM_ERROR)
00274 {
00275 MHD_gnutls_assert ();
00276 result = MHD_gtls_asn2err (result);
00277 goto cleanup;
00278 }
00279
00280
00281
00282
00283 if (str)
00284 size += 16;
00285 asize = size;
00286
00287 data = MHD_gnutls_malloc (size);
00288 if (data == NULL)
00289 {
00290 MHD_gnutls_assert ();
00291 result = GNUTLS_E_MEMORY_ERROR;
00292 goto cleanup;
00293 }
00294
00295 result = MHD__asn1_der_coding (src, src_name, data, &size, NULL);
00296 if (result != ASN1_SUCCESS)
00297 {
00298 MHD_gnutls_assert ();
00299 result = MHD_gtls_asn2err (result);
00300 goto cleanup;
00301 }
00302
00303 if (str)
00304 {
00305 if ((result =
00306 MHD__asn1_create_element (MHD__gnutls_get_pkix (),
00307 "PKIX1.pkcs-7-Data",
00308 &c2)) != ASN1_SUCCESS)
00309 {
00310 MHD_gnutls_assert ();
00311 result = MHD_gtls_asn2err (result);
00312 goto cleanup;
00313 }
00314
00315 result = MHD__asn1_write_value (c2, "", data, size);
00316 if (result != ASN1_SUCCESS)
00317 {
00318 MHD_gnutls_assert ();
00319 result = MHD_gtls_asn2err (result);
00320 goto cleanup;
00321 }
00322
00323 result = MHD__asn1_der_coding (c2, "", data, &asize, NULL);
00324 if (result != ASN1_SUCCESS)
00325 {
00326 MHD_gnutls_assert ();
00327 result = MHD_gtls_asn2err (result);
00328 goto cleanup;
00329 }
00330
00331 size = asize;
00332
00333 MHD__asn1_delete_structure (&c2);
00334 }
00335
00336 res->data = data;
00337 res->size = size;
00338 return 0;
00339
00340 cleanup:MHD_gnutls_free (data);
00341 MHD__asn1_delete_structure (&c2);
00342 return result;
00343
00344 }
00345
00346
00347
00348
00349 int
00350 MHD__gnutls_x509_get_pk_algorithm (ASN1_TYPE src,
00351 const char *src_name, unsigned int *bits)
00352 {
00353 int result;
00354 opaque *str = NULL;
00355 int algo;
00356 char oid[64];
00357 int len;
00358 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
00359 char name[128];
00360
00361 MHD_gtls_str_cpy (name, sizeof (name), src_name);
00362 MHD_gtls_str_cat (name, sizeof (name), ".algorithm.algorithm");
00363
00364 len = sizeof (oid);
00365 result = MHD__asn1_read_value (src, name, oid, &len);
00366
00367 if (result != ASN1_SUCCESS)
00368 {
00369 MHD_gnutls_assert ();
00370 return MHD_gtls_asn2err (result);
00371 }
00372
00373 algo = MHD_gtls_x509_oid2pk_algorithm (oid);
00374
00375 if (bits == NULL)
00376 {
00377 MHD_gnutls_free (str);
00378 return algo;
00379 }
00380
00381
00382
00383 MHD_gtls_str_cpy (name, sizeof (name), src_name);
00384 MHD_gtls_str_cat (name, sizeof (name), ".subjectPublicKey");
00385
00386 len = 0;
00387 result = MHD__asn1_read_value (src, name, NULL, &len);
00388 if (result != ASN1_MEM_ERROR)
00389 {
00390 MHD_gnutls_assert ();
00391 return MHD_gtls_asn2err (result);
00392 }
00393
00394 if (len % 8 != 0)
00395 {
00396 MHD_gnutls_assert ();
00397 return GNUTLS_E_CERTIFICATE_ERROR;
00398 }
00399
00400 len /= 8;
00401
00402 str = MHD_gnutls_malloc (len);
00403 if (str == NULL)
00404 {
00405 MHD_gnutls_assert ();
00406 return GNUTLS_E_MEMORY_ERROR;
00407 }
00408
00409 MHD_gtls_str_cpy (name, sizeof (name), src_name);
00410 MHD_gtls_str_cat (name, sizeof (name), ".subjectPublicKey");
00411
00412 result = MHD__asn1_read_value (src, name, str, &len);
00413
00414 if (result != ASN1_SUCCESS)
00415 {
00416 MHD_gnutls_assert ();
00417 MHD_gnutls_free (str);
00418 return MHD_gtls_asn2err (result);
00419 }
00420
00421 len /= 8;
00422
00423 switch (algo)
00424 {
00425 case MHD_GNUTLS_PK_RSA:
00426 {
00427 if ((result =
00428 MHD__gnutls_x509_read_rsa_params (str, len, params)) < 0)
00429 {
00430 MHD_gnutls_assert ();
00431 return result;
00432 }
00433
00434 bits[0] = MHD__gnutls_mpi_get_nbits (params[0]);
00435
00436 MHD_gtls_mpi_release (¶ms[0]);
00437 MHD_gtls_mpi_release (¶ms[1]);
00438 }
00439 break;
00440 default:
00441 MHD__gnutls_x509_log
00442 ("MHD__gnutls_x509_get_pk_algorithm: unhandled algorithm %d\n", algo);
00443 }
00444
00445 MHD_gnutls_free (str);
00446 return algo;
00447 }