aboutsummaryrefslogtreecommitdiff
path: root/src/daemon/https/x509/x509.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/daemon/https/x509/x509.c')
-rw-r--r--src/daemon/https/x509/x509.c1576
1 files changed, 2 insertions, 1574 deletions
diff --git a/src/daemon/https/x509/x509.c b/src/daemon/https/x509/x509.c
index 599902ca..343030cc 100644
--- a/src/daemon/https/x509/x509.c
+++ b/src/daemon/https/x509/x509.c
@@ -71,62 +71,6 @@ MHD_gnutls_x509_crt_init (MHD_gnutls_x509_crt_t * cert)
71 return 0; /* success */ 71 return 0; /* success */
72} 72}
73 73
74/*-
75 * MHD__gnutls_x509_crt_cpy - This function copies a MHD_gnutls_x509_crt_t structure
76 * @dest: The structure where to copy
77 * @src: The structure to be copied
78 *
79 * This function will copy an X.509 certificate structure.
80 *
81 * Returns 0 on success.
82 *
83 -*/
84int
85MHD__gnutls_x509_crt_cpy (MHD_gnutls_x509_crt_t dest, MHD_gnutls_x509_crt_t src)
86{
87 int ret;
88 size_t der_size;
89 opaque *der;
90 MHD_gnutls_datum_t tmp;
91
92 ret = MHD_gnutls_x509_crt_export (src, GNUTLS_X509_FMT_DER, NULL, &der_size);
93 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
94 {
95 MHD_gnutls_assert ();
96 return ret;
97 }
98
99 der = MHD_gnutls_alloca (der_size);
100 if (der == NULL)
101 {
102 MHD_gnutls_assert ();
103 return GNUTLS_E_MEMORY_ERROR;
104 }
105
106 ret = MHD_gnutls_x509_crt_export (src, GNUTLS_X509_FMT_DER, der, &der_size);
107 if (ret < 0)
108 {
109 MHD_gnutls_assert ();
110 MHD_gnutls_afree (der);
111 return ret;
112 }
113
114 tmp.data = der;
115 tmp.size = der_size;
116 ret = MHD_gnutls_x509_crt_import (dest, &tmp, GNUTLS_X509_FMT_DER);
117
118 MHD_gnutls_afree (der);
119
120 if (ret < 0)
121 {
122 MHD_gnutls_assert ();
123 return ret;
124 }
125
126 return 0;
127
128}
129
130/** 74/**
131 * MHD_gnutls_x509_crt_deinit - This function deinitializes memory used by a MHD_gnutls_x509_crt_t structure 75 * MHD_gnutls_x509_crt_deinit - This function deinitializes memory used by a MHD_gnutls_x509_crt_t structure
132 * @cert: The structure to be initialized 76 * @cert: The structure to be initialized
@@ -233,149 +177,6 @@ cleanup:MHD_gnutls_free (signature);
233} 177}
234 178
235/** 179/**
236 * MHD_gnutls_x509_crt_get_issuer_dn - This function returns the Certificate's issuer distinguished name
237 * @cert: should contain a MHD_gnutls_x509_crt_t structure
238 * @buf: a pointer to a structure to hold the name (may be null)
239 * @sizeof_buf: initially holds the size of @buf
240 *
241 * This function will copy the name of the Certificate issuer in the
242 * provided buffer. The name will be in the form
243 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
244 * will be ASCII or UTF-8 encoded, depending on the certificate data.
245 *
246 * If @buf is null then only the size will be filled.
247 *
248 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
249 * long enough, and in that case the *sizeof_buf will be updated with
250 * the required size. On success 0 is returned.
251 *
252 **/
253int
254MHD_gnutls_x509_crt_get_issuer_dn (MHD_gnutls_x509_crt_t cert,
255 char *buf, size_t * sizeof_buf)
256{
257 if (cert == NULL)
258 {
259 MHD_gnutls_assert ();
260 return GNUTLS_E_INVALID_REQUEST;
261 }
262
263 return MHD__gnutls_x509_parse_dn (cert->cert,
264 "tbsCertificate.issuer.rdnSequence", buf,
265 sizeof_buf);
266}
267
268/**
269 * MHD_gnutls_x509_crt_get_issuer_dn_by_oid - This function returns the Certificate's issuer distinguished name
270 * @cert: should contain a MHD_gnutls_x509_crt_t structure
271 * @oid: holds an Object Identified in null terminated string
272 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
273 * @raw_flag: If non zero returns the raw DER data of the DN part.
274 * @buf: a pointer to a structure to hold the name (may be null)
275 * @sizeof_buf: initially holds the size of @buf
276 *
277 * This function will extract the part of the name of the Certificate
278 * issuer specified by the given OID. The output, if the raw flag is not
279 * used, will be encoded as described in RFC2253. Thus a string that is
280 * ASCII or UTF-8 encoded, depending on the certificate data.
281 *
282 * Some helper macros with popular OIDs can be found in gnutls/x509.h
283 * If raw flag is zero, this function will only return known OIDs as
284 * text. Other OIDs will be DER encoded, as described in RFC2253 --
285 * in hex format with a '\#' prefix. You can check about known OIDs
286 * using MHD_gnutls_x509_dn_oid_known().
287 *
288 * If @buf is null then only the size will be filled.
289 *
290 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
291 * long enough, and in that case the *sizeof_buf will be updated with
292 * the required size. On success 0 is returned.
293 *
294 **/
295int
296MHD_gnutls_x509_crt_get_issuer_dn_by_oid (MHD_gnutls_x509_crt_t cert,
297 const char *oid,
298 int indx,
299 unsigned int raw_flag,
300 void *buf, size_t * sizeof_buf)
301{
302 if (cert == NULL)
303 {
304 MHD_gnutls_assert ();
305 return GNUTLS_E_INVALID_REQUEST;
306 }
307
308 return MHD__gnutls_x509_parse_dn_oid (cert->cert,
309 "tbsCertificate.issuer.rdnSequence", oid,
310 indx, raw_flag, buf, sizeof_buf);
311}
312
313/**
314 * MHD_gnutls_x509_crt_get_issuer_dn_oid - This function returns the Certificate's issuer distinguished name OIDs
315 * @cert: should contain a MHD_gnutls_x509_crt_t structure
316 * @indx: This specifies which OID to return. Use zero to get the first one.
317 * @oid: a pointer to a buffer to hold the OID (may be null)
318 * @sizeof_oid: initially holds the size of @oid
319 *
320 * This function will extract the OIDs of the name of the Certificate
321 * issuer specified by the given index.
322 *
323 * If @oid is null then only the size will be filled.
324 *
325 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
326 * long enough, and in that case the *sizeof_oid will be updated with
327 * the required size. On success 0 is returned.
328 *
329 **/
330int
331MHD_gnutls_x509_crt_get_issuer_dn_oid (MHD_gnutls_x509_crt_t cert,
332 int indx, void *oid, size_t * sizeof_oid)
333{
334 if (cert == NULL)
335 {
336 MHD_gnutls_assert ();
337 return GNUTLS_E_INVALID_REQUEST;
338 }
339
340 return MHD__gnutls_x509_get_dn_oid (cert->cert,
341 "tbsCertificate.issuer.rdnSequence", indx,
342 oid, sizeof_oid);
343}
344
345/**
346 * MHD_gnutls_x509_crt_get_dn - This function returns the Certificate's distinguished name
347 * @cert: should contain a MHD_gnutls_x509_crt_t structure
348 * @buf: a pointer to a structure to hold the name (may be null)
349 * @sizeof_buf: initially holds the size of @buf
350 *
351 * This function will copy the name of the Certificate in the
352 * provided buffer. The name will be in the form
353 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
354 * will be ASCII or UTF-8 encoded, depending on the certificate data.
355 *
356 * If @buf is null then only the size will be filled.
357 *
358 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
359 * long enough, and in that case the *sizeof_buf will be updated with
360 * the required size. On success 0 is returned.
361 *
362 **/
363int
364MHD_gnutls_x509_crt_get_dn (MHD_gnutls_x509_crt_t cert,
365 char *buf, size_t * sizeof_buf)
366{
367 if (cert == NULL)
368 {
369 MHD_gnutls_assert ();
370 return GNUTLS_E_INVALID_REQUEST;
371 }
372
373 return MHD__gnutls_x509_parse_dn (cert->cert,
374 "tbsCertificate.subject.rdnSequence", buf,
375 sizeof_buf);
376}
377
378/**
379 * MHD_gnutls_x509_crt_get_dn_by_oid - This function returns the Certificate's distinguished name 180 * MHD_gnutls_x509_crt_get_dn_by_oid - This function returns the Certificate's distinguished name
380 * @cert: should contain a MHD_gnutls_x509_crt_t structure 181 * @cert: should contain a MHD_gnutls_x509_crt_t structure
381 * @oid: holds an Object Identified in null terminated string 182 * @oid: holds an Object Identified in null terminated string
@@ -421,38 +222,6 @@ MHD_gnutls_x509_crt_get_dn_by_oid (MHD_gnutls_x509_crt_t cert,
421} 222}
422 223
423/** 224/**
424 * MHD_gnutls_x509_crt_get_dn_oid - This function returns the Certificate's subject distinguished name OIDs
425 * @cert: should contain a MHD_gnutls_x509_crt_t structure
426 * @indx: This specifies which OID to return. Use zero to get the first one.
427 * @oid: a pointer to a buffer to hold the OID (may be null)
428 * @sizeof_oid: initially holds the size of @oid
429 *
430 * This function will extract the OIDs of the name of the Certificate
431 * subject specified by the given index.
432 *
433 * If oid is null then only the size will be filled.
434 *
435 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
436 * long enough, and in that case the *sizeof_oid will be updated with
437 * the required size. On success 0 is returned.
438 *
439 **/
440int
441MHD_gnutls_x509_crt_get_dn_oid (MHD_gnutls_x509_crt_t cert,
442 int indx, void *oid, size_t * sizeof_oid)
443{
444 if (cert == NULL)
445 {
446 MHD_gnutls_assert ();
447 return GNUTLS_E_INVALID_REQUEST;
448 }
449
450 return MHD__gnutls_x509_get_dn_oid (cert->cert,
451 "tbsCertificate.subject.rdnSequence", indx,
452 oid, sizeof_oid);
453}
454
455/**
456 * MHD_gnutls_x509_crt_get_signature_algorithm - This function returns the Certificate's signature algorithm 225 * MHD_gnutls_x509_crt_get_signature_algorithm - This function returns the Certificate's signature algorithm
457 * @cert: should contain a MHD_gnutls_x509_crt_t structure 226 * @cert: should contain a MHD_gnutls_x509_crt_t structure
458 * 227 *
@@ -671,179 +440,6 @@ MHD_gnutls_x509_crt_get_serial (MHD_gnutls_x509_crt_t cert,
671 return 0; 440 return 0;
672} 441}
673 442
674/**
675 * MHD_gnutls_x509_crt_get_subject_key_id - This function returns the certificate's key identifier
676 * @cert: should contain a MHD_gnutls_x509_crt_t structure
677 * @ret: The place where the identifier will be copied
678 * @ret_size: Holds the size of the result field.
679 * @critical: will be non zero if the extension is marked as critical (may be null)
680 *
681 * This function will return the X.509v3 certificate's subject key identifier.
682 * This is obtained by the X.509 Subject Key identifier extension
683 * field (2.5.29.14).
684 *
685 * Returns 0 on success and a negative value in case of an error.
686 *
687 **/
688int
689MHD_gnutls_x509_crt_get_subject_key_id (MHD_gnutls_x509_crt_t cert,
690 void *ret,
691 size_t * ret_size, unsigned int *critical)
692{
693 int result, len;
694 MHD_gnutls_datum_t id;
695 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
696
697 if (cert == NULL)
698 {
699 MHD_gnutls_assert ();
700 return GNUTLS_E_INVALID_REQUEST;
701 }
702
703 if (ret)
704 memset (ret, 0, *ret_size);
705 else
706 *ret_size = 0;
707
708 if ((result = MHD__gnutls_x509_crt_get_extension (cert, "2.5.29.14", 0, &id,
709 critical)) < 0)
710 {
711 return result;
712 }
713
714 if (id.size == 0 || id.data == NULL)
715 {
716 MHD_gnutls_assert ();
717 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
718 }
719
720 result =
721 MHD__asn1_create_element (MHD__gnutls_get_pkix (), "PKIX1.SubjectKeyIdentifier",
722 &c2);
723 if (result != ASN1_SUCCESS)
724 {
725 MHD_gnutls_assert ();
726 MHD__gnutls_free_datum (&id);
727 return MHD_gtls_asn2err (result);
728 }
729
730 result = MHD__asn1_der_decoding (&c2, id.data, id.size, NULL);
731 MHD__gnutls_free_datum (&id);
732
733 if (result != ASN1_SUCCESS)
734 {
735 MHD_gnutls_assert ();
736 MHD__asn1_delete_structure (&c2);
737 return MHD_gtls_asn2err (result);
738 }
739
740 len = *ret_size;
741 result = MHD__asn1_read_value (c2, "", ret, &len);
742
743 *ret_size = len;
744 MHD__asn1_delete_structure (&c2);
745
746 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
747 {
748 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
749 }
750
751 if (result != ASN1_SUCCESS)
752 {
753 MHD_gnutls_assert ();
754 return MHD_gtls_asn2err (result);
755 }
756
757 return 0;
758}
759
760/**
761 * MHD_gnutls_x509_crt_get_authority_key_id - This function returns the certificate authority's identifier
762 * @cert: should contain a MHD_gnutls_x509_crt_t structure
763 * @result: The place where the identifier will be copied
764 * @result_size: Holds the size of the result field.
765 * @critical: will be non zero if the extension is marked as critical (may be null)
766 *
767 * This function will return the X.509v3 certificate authority's key identifier.
768 * This is obtained by the X.509 Authority Key identifier extension
769 * field (2.5.29.35). Note that this function only returns the keyIdentifier
770 * field of the extension.
771 *
772 * Returns 0 on success and a negative value in case of an error.
773 *
774 **/
775int
776MHD_gnutls_x509_crt_get_authority_key_id (MHD_gnutls_x509_crt_t cert,
777 void *ret,
778 size_t * ret_size,
779 unsigned int *critical)
780{
781 int result, len;
782 MHD_gnutls_datum_t id;
783 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
784
785 if (cert == NULL)
786 {
787 MHD_gnutls_assert ();
788 return GNUTLS_E_INVALID_REQUEST;
789 }
790
791 if (ret)
792 memset (ret, 0, *ret_size);
793 else
794 *ret_size = 0;
795
796 if ((result = MHD__gnutls_x509_crt_get_extension (cert, "2.5.29.35", 0, &id,
797 critical)) < 0)
798 {
799 return result;
800 }
801
802 if (id.size == 0 || id.data == NULL)
803 {
804 MHD_gnutls_assert ();
805 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
806 }
807
808 result =
809 MHD__asn1_create_element (MHD__gnutls_get_pkix (), "PKIX1.AuthorityKeyIdentifier",
810 &c2);
811 if (result != ASN1_SUCCESS)
812 {
813 MHD_gnutls_assert ();
814 MHD__gnutls_free_datum (&id);
815 return MHD_gtls_asn2err (result);
816 }
817
818 result = MHD__asn1_der_decoding (&c2, id.data, id.size, NULL);
819 MHD__gnutls_free_datum (&id);
820
821 if (result != ASN1_SUCCESS)
822 {
823 MHD_gnutls_assert ();
824 MHD__asn1_delete_structure (&c2);
825 return MHD_gtls_asn2err (result);
826 }
827
828 len = *ret_size;
829 result = MHD__asn1_read_value (c2, "keyIdentifier", ret, &len);
830
831 *ret_size = len;
832 MHD__asn1_delete_structure (&c2);
833
834 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
835 {
836 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
837 }
838
839 if (result != ASN1_SUCCESS)
840 {
841 MHD_gnutls_assert ();
842 return MHD_gtls_asn2err (result);
843 }
844
845 return 0;
846}
847 443
848/** 444/**
849 * MHD_gnutls_x509_crt_get_pk_algorithm - This function returns the certificate's PublicKey algorithm 445 * MHD_gnutls_x509_crt_get_pk_algorithm - This function returns the certificate's PublicKey algorithm
@@ -1194,70 +790,6 @@ MHD_gnutls_x509_crt_get_subject_alt_name (MHD_gnutls_x509_crt_t cert,
1194} 790}
1195 791
1196/** 792/**
1197 * MHD_gnutls_x509_crt_get_subject_alt_name2 - Get certificate's alternative name, if any
1198 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1199 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1200 * @ret: is the place where the alternative name will be copied to
1201 * @ret_size: holds the size of ret.
1202 * @ret_type: holds the type of the alternative name (one of MHD_gnutls_x509_subject_alt_name_t).
1203 * @critical: will be non zero if the extension is marked as critical (may be null)
1204 *
1205 * This function will return the alternative names, contained in the
1206 * given certificate. It is the same as MHD_gnutls_x509_crt_get_subject_alt_name()
1207 * except for the fact that it will return the type of the alternative
1208 * name in @ret_type even if the function fails for some reason (i.e.
1209 * the buffer provided is not enough).
1210 *
1211 * The return values are the same as with MHD_gnutls_x509_crt_get_subject_alt_name().
1212 *
1213 **/
1214int
1215MHD_gnutls_x509_crt_get_subject_alt_name2 (MHD_gnutls_x509_crt_t cert,
1216 unsigned int seq,
1217 void *ret,
1218 size_t * ret_size,
1219 unsigned int *ret_type,
1220 unsigned int *critical)
1221{
1222 return get_subject_alt_name (cert, seq, ret, ret_size, ret_type, critical,
1223 0);
1224}
1225
1226/**
1227 * MHD_gnutls_x509_crt_get_subject_alt_othername_oid - Get SAN otherName OID
1228 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1229 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1230 * @ret: is the place where the otherName OID will be copied to
1231 * @ret_size: holds the size of ret.
1232 *
1233 * This function will extract the type OID of an otherName Subject
1234 * Alternative Name, contained in the given certificate, and return
1235 * the type as an enumerated element.
1236 *
1237 * This function is only useful if
1238 * MHD_gnutls_x509_crt_get_subject_alt_name() returned
1239 * %GNUTLS_SAN_OTHERNAME.
1240 *
1241 * Returns the alternative subject name type on success. The type is
1242 * one of the enumerated MHD_gnutls_x509_subject_alt_name_t. For
1243 * supported OIDs, it will return one of the virtual
1244 * (GNUTLS_SAN_OTHERNAME_*) types, e.g. %GNUTLS_SAN_OTHERNAME_XMPP,
1245 * and %GNUTLS_SAN_OTHERNAME for unknown OIDs. It will return
1246 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large enough to
1247 * hold the value. In that case @ret_size will be updated with the
1248 * required size. If the certificate does not have an Alternative
1249 * name with the specified sequence number and with the otherName type
1250 * then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1251 **/
1252int
1253MHD_gnutls_x509_crt_get_subject_alt_othername_oid (MHD_gnutls_x509_crt_t cert,
1254 unsigned int seq,
1255 void *ret, size_t * ret_size)
1256{
1257 return get_subject_alt_name (cert, seq, ret, ret_size, NULL, NULL, 1);
1258}
1259
1260/**
1261 * MHD_gnutls_x509_crt_get_basic_constraints - This function returns the certificate basic constraints 793 * MHD_gnutls_x509_crt_get_basic_constraints - This function returns the certificate basic constraints
1262 * @cert: should contain a MHD_gnutls_x509_crt_t structure 794 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1263 * @critical: will be non zero if the extension is marked as critical 795 * @critical: will be non zero if the extension is marked as critical
@@ -1277,7 +809,7 @@ MHD_gnutls_x509_crt_get_subject_alt_othername_oid (MHD_gnutls_x509_crt_t cert,
1277 * certificate does not contain the basicConstraints extension 809 * certificate does not contain the basicConstraints extension
1278 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. 810 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1279 **/ 811 **/
1280int 812static int
1281MHD_gnutls_x509_crt_get_basic_constraints (MHD_gnutls_x509_crt_t cert, 813MHD_gnutls_x509_crt_get_basic_constraints (MHD_gnutls_x509_crt_t cert,
1282 unsigned int *critical, 814 unsigned int *critical,
1283 int *ca, int *pathlen) 815 int *ca, int *pathlen)
@@ -1409,66 +941,6 @@ MHD_gnutls_x509_crt_get_key_usage (MHD_gnutls_x509_crt_t cert,
1409 return 0; 941 return 0;
1410} 942}
1411 943
1412/**
1413 * MHD_gnutls_x509_crt_get_proxy - This function returns the proxy certificate info
1414 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1415 * @critical: will be non zero if the extension is marked as critical
1416 * @pathlen: pointer to output integer indicating path length (may be
1417 * NULL), non-negative values indicate a present pCPathLenConstraint
1418 * field and the actual value, -1 indicate that the field is absent.
1419 *
1420 * This function will read the certificate's basic constraints, and
1421 * return the certificates CA status. It reads the basicConstraints
1422 * X.509 extension (2.5.29.19).
1423 *
1424 * Return value: If the certificate is a CA a positive value will be
1425 * returned, or zero if the certificate does not have CA flag set. A
1426 * negative value may be returned in case of errors. If the
1427 * certificate does not contain the basicConstraints extension
1428 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1429 **/
1430int
1431MHD_gnutls_x509_crt_get_proxy (MHD_gnutls_x509_crt_t cert,
1432 unsigned int *critical,
1433 int *pathlen,
1434 char **policyLanguage,
1435 char **policy, size_t * sizeof_policy)
1436{
1437 int result;
1438 MHD_gnutls_datum_t proxyCertInfo;
1439
1440 if (cert == NULL)
1441 {
1442 MHD_gnutls_assert ();
1443 return GNUTLS_E_INVALID_REQUEST;
1444 }
1445
1446 if ((result = MHD__gnutls_x509_crt_get_extension (cert, "1.3.6.1.5.5.7.1.14", 0,
1447 &proxyCertInfo,
1448 critical)) < 0)
1449 {
1450 return result;
1451 }
1452
1453 if (proxyCertInfo.size == 0 || proxyCertInfo.data == NULL)
1454 {
1455 MHD_gnutls_assert ();
1456 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1457 }
1458
1459 result = MHD__gnutls_x509_ext_extract_proxyCertInfo (pathlen, policyLanguage,
1460 policy, sizeof_policy,
1461 proxyCertInfo.data,
1462 proxyCertInfo.size);
1463 MHD__gnutls_free_datum (&proxyCertInfo);
1464 if (result < 0)
1465 {
1466 MHD_gnutls_assert ();
1467 return result;
1468 }
1469
1470 return 0;
1471}
1472 944
1473/** 945/**
1474 * MHD_gnutls_x509_crt_get_extension_by_oid - This function returns the specified extension 946 * MHD_gnutls_x509_crt_get_extension_by_oid - This function returns the specified extension
@@ -1488,7 +960,7 @@ MHD_gnutls_x509_crt_get_proxy (MHD_gnutls_x509_crt_t cert,
1488 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned. 960 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1489 * 961 *
1490 **/ 962 **/
1491int 963static int
1492MHD_gnutls_x509_crt_get_extension_by_oid (MHD_gnutls_x509_crt_t cert, 964MHD_gnutls_x509_crt_get_extension_by_oid (MHD_gnutls_x509_crt_t cert,
1493 const char *oid, 965 const char *oid,
1494 int indx, 966 int indx,
@@ -1536,167 +1008,6 @@ MHD_gnutls_x509_crt_get_extension_by_oid (MHD_gnutls_x509_crt_t cert,
1536 1008
1537} 1009}
1538 1010
1539/**
1540 * MHD_gnutls_x509_crt_get_extension_oid - This function returns the specified extension OID
1541 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1542 * @indx: Specifies which extension OID to send. Use zero to get the first one.
1543 * @oid: a pointer to a structure to hold the OID (may be null)
1544 * @sizeof_oid: initially holds the size of @oid
1545 *
1546 * This function will return the requested extension OID in the certificate.
1547 * The extension OID will be stored as a string in the provided buffer.
1548 *
1549 * A negative value may be returned in case of parsing error.
1550 * If your have reached the last extension available
1551 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1552 *
1553 **/
1554int
1555MHD_gnutls_x509_crt_get_extension_oid (MHD_gnutls_x509_crt_t cert,
1556 int indx, void *oid, size_t * sizeof_oid)
1557{
1558 int result;
1559
1560 if (cert == NULL)
1561 {
1562 MHD_gnutls_assert ();
1563 return GNUTLS_E_INVALID_REQUEST;
1564 }
1565
1566 result = MHD__gnutls_x509_crt_get_extension_oid (cert, indx, oid, sizeof_oid);
1567 if (result < 0)
1568 {
1569 return result;
1570 }
1571
1572 return 0;
1573
1574}
1575
1576/**
1577 * MHD_gnutls_x509_crt_get_extension_info - Get extension id and criticality
1578 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1579 * @indx: Specifies which extension OID to send. Use zero to get the first one.
1580 * @oid: a pointer to a structure to hold the OID
1581 * @sizeof_oid: initially holds the size of @oid
1582 * @critical: output variable with critical flag, may be NULL.
1583 *
1584 * This function will return the requested extension OID in the
1585 * certificate, and the critical flag for it. The extension OID will
1586 * be stored as a string in the provided buffer. Use
1587 * MHD_gnutls_x509_crt_get_extension_data() to extract the data.
1588 *
1589 * Return 0 on success. A negative value may be returned in case of
1590 * parsing error. If you have reached the last extension available
1591 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1592 *
1593 **/
1594int
1595MHD_gnutls_x509_crt_get_extension_info (MHD_gnutls_x509_crt_t cert,
1596 int indx,
1597 void *oid,
1598 size_t * sizeof_oid, int *critical)
1599{
1600 int result;
1601 char str_critical[10];
1602 char name[MAX_NAME_SIZE];
1603 int len;
1604
1605 if (!cert)
1606 {
1607 MHD_gnutls_assert ();
1608 return GNUTLS_E_INVALID_REQUEST;
1609 }
1610
1611 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnID",
1612 indx + 1);
1613
1614 len = *sizeof_oid;
1615 result = MHD__asn1_read_value (cert->cert, name, oid, &len);
1616 *sizeof_oid = len;
1617
1618 if (result == ASN1_ELEMENT_NOT_FOUND)
1619 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1620 else if (result < 0)
1621 {
1622 MHD_gnutls_assert ();
1623 return MHD_gtls_asn2err (result);
1624 }
1625
1626 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.critical",
1627 indx + 1);
1628 len = sizeof (str_critical);
1629 result = MHD__asn1_read_value (cert->cert, name, str_critical, &len);
1630 if (result < 0)
1631 {
1632 MHD_gnutls_assert ();
1633 return MHD_gtls_asn2err (result);
1634 }
1635
1636 if (critical)
1637 {
1638 if (str_critical[0] == 'T')
1639 *critical = 1;
1640 else
1641 *critical = 0;
1642 }
1643
1644 return 0;
1645
1646}
1647
1648/**
1649 * MHD_gnutls_x509_crt_get_extension_data - Get the specified extension data
1650 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1651 * @indx: Specifies which extension OID to send. Use zero to get the first one.
1652 * @data: a pointer to a structure to hold the data (may be null)
1653 * @sizeof_data: initially holds the size of @oid
1654 *
1655 * This function will return the requested extension data in the
1656 * certificate. The extension data will be stored as a string in the
1657 * provided buffer.
1658 *
1659 * Use MHD_gnutls_x509_crt_get_extension_info() to extract the OID and
1660 * critical flag. Use MHD_gnutls_x509_crt_get_extension_by_oid() instead,
1661 * if you want to get data indexed by the extension OID rather than
1662 * sequence.
1663 *
1664 * Return 0 on success. A negative value may be returned in case of
1665 * parsing error. If you have reached the last extension available
1666 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1667 **/
1668int
1669MHD_gnutls_x509_crt_get_extension_data (MHD_gnutls_x509_crt_t cert,
1670 int indx,
1671 void *data, size_t * sizeof_data)
1672{
1673 int result, len;
1674 char name[MAX_NAME_SIZE];
1675
1676 if (!cert)
1677 {
1678 MHD_gnutls_assert ();
1679 return GNUTLS_E_INVALID_REQUEST;
1680 }
1681
1682 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnValue",
1683 indx + 1);
1684
1685 len = *sizeof_data;
1686 result = MHD__asn1_read_value (cert->cert, name, data, &len);
1687 *sizeof_data = len;
1688
1689 if (result == ASN1_ELEMENT_NOT_FOUND)
1690 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1691 else if (result < 0)
1692 {
1693 MHD_gnutls_assert ();
1694 return MHD_gtls_asn2err (result);
1695 }
1696
1697 return 0;
1698}
1699
1700static int 1011static int
1701MHD__gnutls_x509_crt_get_raw_dn2 (MHD_gnutls_x509_crt_t cert, 1012MHD__gnutls_x509_crt_get_raw_dn2 (MHD_gnutls_x509_crt_t cert,
1702 const char *whom, MHD_gnutls_datum_t * start) 1013 const char *whom, MHD_gnutls_datum_t * start)
@@ -1817,171 +1128,6 @@ MHD_gnutls_x509_crt_get_subject (MHD_gnutls_x509_crt_t cert, MHD_gnutls_x509_dn_
1817} 1128}
1818 1129
1819/** 1130/**
1820 * MHD_gnutls_x509_crt_get_issuer: get opaque issuer DN pointer
1821 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1822 * @dn: output variable with pointer to opaque DN
1823 *
1824 * Return the Certificate's Issuer DN as an opaque data type. You may
1825 * use MHD_gnutls_x509_dn_get_rdn_ava() to decode the DN.
1826 *
1827 * Note that @dn points into the @cert object, and thus you may not
1828 * deallocate @cert and continue to access @dn.
1829 *
1830 * Returns: Returns 0 on success, or an error code.
1831 **/
1832int
1833MHD_gnutls_x509_crt_get_issuer (MHD_gnutls_x509_crt_t cert, MHD_gnutls_x509_dn_t * dn)
1834{
1835 return get_dn (cert, "tbsCertificate.issuer.rdnSequence", dn);
1836}
1837
1838/**
1839 * MHD_gnutls_x509_dn_get_rdn_ava:
1840 * @dn: input variable with opaque DN pointer
1841 * @irdn: index of RDN
1842 * @iava: index of AVA.
1843 * @ava: Pointer to structure which will hold output information.
1844 *
1845 * Get pointers to data within the DN.
1846 *
1847 * Note that @ava will contain pointers into the @dn structure, so you
1848 * should not modify any data or deallocate it. Note also that the DN
1849 * in turn points into the original certificate structure, and thus
1850 * you may not deallocate the certificate and continue to access @dn.
1851 *
1852 * Returns: Returns 0 on success, or an error code.
1853 **/
1854int
1855MHD_gnutls_x509_dn_get_rdn_ava (MHD_gnutls_x509_dn_t dn,
1856 int irdn, int iava, MHD_gnutls_x509_ava_st * ava)
1857{
1858 ASN1_TYPE rdn, elem;
1859 long len;
1860 int lenlen, remlen, ret;
1861 char rbuf[MAX_NAME_SIZE];
1862 unsigned char cls, *ptr;
1863
1864 iava++;
1865 irdn++; /* 0->1, 1->2 etc */
1866
1867 snprintf (rbuf, sizeof (rbuf), "rdnSequence.?%d.?%d", irdn, iava);
1868 rdn = MHD__asn1_find_node (dn, rbuf);
1869 if (!rdn)
1870 {
1871 MHD_gnutls_assert ();
1872 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
1873 }
1874
1875 snprintf (rbuf, sizeof (rbuf), "?%d.type", iava);
1876 elem = MHD__asn1_find_node (rdn, rbuf);
1877 if (!elem)
1878 {
1879 MHD_gnutls_assert ();
1880 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
1881 }
1882
1883 ava->oid.data = elem->value;
1884 ava->oid.size = elem->value_len;
1885
1886 snprintf (rbuf, sizeof (rbuf), "?%d.value", iava);
1887 elem = MHD__asn1_find_node (rdn, rbuf);
1888 if (!elem)
1889 {
1890 MHD_gnutls_assert ();
1891 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
1892 }
1893
1894 /* The value still has the previous tag's length bytes, plus the
1895 * current value's tag and length bytes. Decode them.
1896 */
1897
1898 ptr = elem->value;
1899 remlen = elem->value_len;
1900 len = MHD__asn1_get_length_der (ptr, remlen, &lenlen);
1901 if (len < 0)
1902 {
1903 MHD_gnutls_assert ();
1904 return GNUTLS_E_ASN1_DER_ERROR;
1905 }
1906
1907 ptr += lenlen;
1908 remlen -= lenlen;
1909 ret = MHD__asn1_get_tag_der (ptr, remlen, &cls, &lenlen, &ava->value_tag);
1910 if (ret)
1911 {
1912 MHD_gnutls_assert ();
1913 return MHD_gtls_asn2err (ret);
1914 }
1915
1916 ptr += lenlen;
1917 remlen -= lenlen;
1918
1919 ava->value.size = MHD__asn1_get_length_der (ptr, remlen, &lenlen);
1920 ava->value.data = ptr + lenlen;
1921
1922 return 0;
1923}
1924
1925/**
1926 * MHD_gnutls_x509_crt_get_fingerprint - This function returns the Certificate's fingerprint
1927 * @cert: should contain a MHD_gnutls_x509_crt_t structure
1928 * @algo: is a digest algorithm
1929 * @buf: a pointer to a structure to hold the fingerprint (may be null)
1930 * @sizeof_buf: initially holds the size of @buf
1931 *
1932 * This function will calculate and copy the certificate's fingerprint
1933 * in the provided buffer.
1934 *
1935 * If the buffer is null then only the size will be filled.
1936 *
1937 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
1938 * not long enough, and in that case the *sizeof_buf will be updated
1939 * with the required size. On success 0 is returned.
1940 **/
1941int
1942MHD_gnutls_x509_crt_get_fingerprint (MHD_gnutls_x509_crt_t cert,
1943 enum MHD_GNUTLS_HashAlgorithm algo,
1944 void *buf, size_t * sizeof_buf)
1945{
1946 opaque *cert_buf;
1947 int cert_buf_size;
1948 int result;
1949 MHD_gnutls_datum_t tmp;
1950
1951 if (sizeof_buf == 0 || cert == NULL)
1952 {
1953 return GNUTLS_E_INVALID_REQUEST;
1954 }
1955
1956 cert_buf_size = 0;
1957 MHD__asn1_der_coding (cert->cert, "", NULL, &cert_buf_size, NULL);
1958
1959 cert_buf = MHD_gnutls_alloca (cert_buf_size);
1960 if (cert_buf == NULL)
1961 {
1962 MHD_gnutls_assert ();
1963 return GNUTLS_E_MEMORY_ERROR;
1964 }
1965
1966 result = MHD__asn1_der_coding (cert->cert, "", cert_buf, &cert_buf_size, NULL);
1967
1968 if (result != ASN1_SUCCESS)
1969 {
1970 MHD_gnutls_assert ();
1971 MHD_gnutls_afree (cert_buf);
1972 return MHD_gtls_asn2err (result);
1973 }
1974
1975 tmp.data = cert_buf;
1976 tmp.size = cert_buf_size;
1977
1978 result = MHD__gnutls_fingerprint (algo, &tmp, buf, sizeof_buf);
1979 MHD_gnutls_afree (cert_buf);
1980
1981 return result;
1982}
1983
1984/**
1985 * MHD_gnutls_x509_crt_export - This function will export the certificate 1131 * MHD_gnutls_x509_crt_export - This function will export the certificate
1986 * @cert: Holds the certificate 1132 * @cert: Holds the certificate
1987 * @format: the format of output params. One of PEM or DER. 1133 * @format: the format of output params. One of PEM or DER.
@@ -2016,158 +1162,6 @@ MHD_gnutls_x509_crt_export (MHD_gnutls_x509_crt_t cert,
2016 output_data, output_data_size); 1162 output_data, output_data_size);
2017} 1163}
2018 1164
2019static int
2020rsadsa_get_key_id (MHD_gnutls_x509_crt_t crt,
2021 int pk,
2022 unsigned char *output_data, size_t * output_data_size)
2023{
2024 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
2025 int params_size = MAX_PUBLIC_PARAMS_SIZE;
2026 int i, result = 0;
2027 MHD_gnutls_datum_t der = { NULL,
2028 0
2029 };
2030 GNUTLS_HASH_HANDLE hd;
2031
2032 result = MHD__gnutls_x509_crt_get_mpis (crt, params, &params_size);
2033 if (result < 0)
2034 {
2035 MHD_gnutls_assert ();
2036 return result;
2037 }
2038
2039 if (pk == MHD_GNUTLS_PK_RSA)
2040 {
2041 result = MHD__gnutls_x509_write_rsa_params (params, params_size, &der);
2042 if (result < 0)
2043 {
2044 MHD_gnutls_assert ();
2045 goto cleanup;
2046 }
2047 }
2048 else
2049 return GNUTLS_E_INTERNAL_ERROR;
2050
2051 hd = MHD_gtls_hash_init (MHD_GNUTLS_MAC_SHA1);
2052 if (hd == GNUTLS_HASH_FAILED)
2053 {
2054 MHD_gnutls_assert ();
2055 result = GNUTLS_E_INTERNAL_ERROR;
2056 goto cleanup;
2057 }
2058
2059 MHD_gnutls_hash (hd, der.data, der.size);
2060
2061 MHD_gnutls_hash_deinit (hd, output_data);
2062 *output_data_size = 20;
2063
2064 result = 0;
2065
2066cleanup:
2067
2068 MHD__gnutls_free_datum (&der);
2069
2070 /* release all allocated MPIs
2071 */
2072 for (i = 0; i < params_size; i++)
2073 {
2074 MHD_gtls_mpi_release (&params[i]);
2075 }
2076 return result;
2077}
2078
2079/**
2080 * MHD_gnutls_x509_crt_get_key_id - Return unique ID of public key's parameters
2081 * @crt: Holds the certificate
2082 * @flags: should be 0 for now
2083 * @output_data: will contain the key ID
2084 * @output_data_size: holds the size of output_data (and will be
2085 * replaced by the actual size of parameters)
2086 *
2087 * This function will return a unique ID the depends on the public
2088 * key parameters. This ID can be used in checking whether a
2089 * certificate corresponds to the given private key.
2090 *
2091 * If the buffer provided is not long enough to hold the output, then
2092 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2093 * be returned. The output will normally be a SHA-1 hash output,
2094 * which is 20 bytes.
2095 *
2096 * Return value: In case of failure a negative value will be
2097 * returned, and 0 on success.
2098 **/
2099int
2100MHD_gnutls_x509_crt_get_key_id (MHD_gnutls_x509_crt_t crt,
2101 unsigned int flags,
2102 unsigned char *output_data,
2103 size_t * output_data_size)
2104{
2105 int pk, result = 0;
2106 MHD_gnutls_datum_t pubkey;
2107
2108 if (crt == NULL)
2109 {
2110 MHD_gnutls_assert ();
2111 return GNUTLS_E_INVALID_REQUEST;
2112 }
2113
2114 if (*output_data_size < 20)
2115 {
2116 MHD_gnutls_assert ();
2117 *output_data_size = 20;
2118 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2119 }
2120
2121 pk = MHD_gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2122 if (pk < 0)
2123 {
2124 MHD_gnutls_assert ();
2125 return pk;
2126 }
2127
2128 if (pk == MHD_GNUTLS_PK_RSA)
2129 {
2130 /* This is for compatibility with what GnuTLS has printed for
2131 RSA/DSA before the code below was added. The code below is
2132 applicable to all types, and it would probably be a better
2133 idea to use it for RSA/DSA too, but doing so would break
2134 backwards compatibility. */
2135 return rsadsa_get_key_id (crt, pk, output_data, output_data_size);
2136 }
2137
2138 pubkey.size = 0;
2139 result = MHD__asn1_der_coding (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
2140 NULL, &pubkey.size, NULL);
2141 if (result != ASN1_MEM_ERROR)
2142 {
2143 MHD_gnutls_assert ();
2144 return MHD_gtls_asn2err (result);
2145 }
2146
2147 pubkey.data = MHD_gnutls_alloca (pubkey.size);
2148 if (pubkey.data == NULL)
2149 {
2150 MHD_gnutls_assert ();
2151 return GNUTLS_E_MEMORY_ERROR;
2152 }
2153
2154 result = MHD__asn1_der_coding (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
2155 pubkey.data, &pubkey.size, NULL);
2156 if (result != ASN1_SUCCESS)
2157 {
2158 MHD_gnutls_assert ();
2159 MHD_gnutls_afree (pubkey.data);
2160 return MHD_gtls_asn2err (result);
2161 }
2162
2163 result = MHD__gnutls_fingerprint (MHD_GNUTLS_MAC_SHA1, &pubkey, output_data,
2164 output_data_size);
2165
2166 MHD_gnutls_afree (pubkey.data);
2167
2168 return result;
2169}
2170
2171#ifdef ENABLE_PKI 1165#ifdef ENABLE_PKI
2172 1166
2173/** 1167/**
@@ -2276,571 +1270,5 @@ MHD_gnutls_x509_crt_check_revocation (MHD_gnutls_x509_crt_t cert,
2276 return 0; /* not revoked. */ 1270 return 0; /* not revoked. */
2277} 1271}
2278 1272
2279/**
2280 * MHD_gnutls_x509_crt_verify_data - This function will verify the given signed data.
2281 * @crt: Holds the certificate
2282 * @flags: should be 0 for now
2283 * @data: holds the data to be signed
2284 * @signature: contains the signature
2285 *
2286 * This function will verify the given signed data, using the
2287 * parameters from the certificate.
2288 *
2289 * Returns: In case of a verification failure 0 is returned, and 1 on
2290 * success.
2291 **/
2292int
2293MHD_gnutls_x509_crt_verify_data (MHD_gnutls_x509_crt_t crt,
2294 unsigned int flags,
2295 const MHD_gnutls_datum_t * data,
2296 const MHD_gnutls_datum_t * signature)
2297{
2298 int result;
2299
2300 if (crt == NULL)
2301 {
2302 MHD_gnutls_assert ();
2303 return GNUTLS_E_INVALID_REQUEST;
2304 }
2305
2306 result = MHD__gnutls_x509_verify_signature (data, signature, crt);
2307 if (result < 0)
2308 {
2309 MHD_gnutls_assert ();
2310 return 0;
2311 }
2312
2313 return result;
2314}
2315
2316/**
2317 * MHD_gnutls_x509_crt_get_crl_dist_points - This function returns the CRL distribution points
2318 * @cert: should contain a MHD_gnutls_x509_crt_t structure
2319 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
2320 * @ret: is the place where the distribution point will be copied to
2321 * @ret_size: holds the size of ret.
2322 * @reason_flags: Revocation reasons flags.
2323 * @critical: will be non zero if the extension is marked as critical (may be null)
2324 *
2325 * This function will return the CRL distribution points (2.5.29.31),
2326 * contained in the given certificate.
2327 *
2328 * @reason_flags should be an ORed sequence of
2329 * GNUTLS_CRL_REASON_UNUSED, GNUTLS_CRL_REASON_KEY_COMPROMISE,
2330 * GNUTLS_CRL_REASON_CA_COMPROMISE,
2331 * GNUTLS_CRL_REASON_AFFILIATION_CHANGED,
2332 * GNUTLS_CRL_REASON_SUPERSEEDED,
2333 * GNUTLS_CRL_REASON_CESSATION_OF_OPERATION,
2334 * GNUTLS_CRL_REASON_CERTIFICATE_HOLD,
2335 * GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN,
2336 * GNUTLS_CRL_REASON_AA_COMPROMISE, or zero for all possible reasons.
2337 *
2338 * This is specified in X509v3 Certificate Extensions. GNUTLS will
2339 * return the distribution point type, or a negative error code on
2340 * error.
2341 *
2342 * Returns %GNUTLS_E_SHORT_MEMORY_BUFFER and updates &@ret_size if
2343 * &@ret_size is not enough to hold the distribution point, or the
2344 * type of the distribution point if everything was ok. The type is
2345 * one of the enumerated %MHD_gnutls_x509_subject_alt_name_t. If the
2346 * certificate does not have an Alternative name with the specified
2347 * sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
2348 * returned.
2349 **/
2350int
2351MHD_gnutls_x509_crt_get_crl_dist_points (MHD_gnutls_x509_crt_t cert,
2352 unsigned int seq,
2353 void *ret,
2354 size_t * ret_size,
2355 unsigned int *reason_flags,
2356 unsigned int *critical)
2357{
2358 int result;
2359 MHD_gnutls_datum_t dist_points = { NULL,
2360 0
2361 };
2362 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2363 char name[MAX_NAME_SIZE];
2364 int len;
2365 MHD_gnutls_x509_subject_alt_name_t type;
2366 uint8_t reasons[2];
2367
2368 if (cert == NULL)
2369 {
2370 MHD_gnutls_assert ();
2371 return GNUTLS_E_INVALID_REQUEST;
2372 }
2373
2374 if (*ret_size > 0 && ret)
2375 memset (ret, 0, *ret_size);
2376 else
2377 *ret_size = 0;
2378
2379 if (reason_flags)
2380 *reason_flags = 0;
2381
2382 result = MHD__gnutls_x509_crt_get_extension (cert, "2.5.29.31", 0, &dist_points,
2383 critical);
2384 if (result < 0)
2385 {
2386 return result;
2387 }
2388
2389 if (dist_points.size == 0 || dist_points.data == NULL)
2390 {
2391 MHD_gnutls_assert ();
2392 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2393 }
2394
2395 result =
2396 MHD__asn1_create_element (MHD__gnutls_get_pkix (), "PKIX1.CRLDistributionPoints",
2397 &c2);
2398 if (result != ASN1_SUCCESS)
2399 {
2400 MHD_gnutls_assert ();
2401 MHD__gnutls_free_datum (&dist_points);
2402 return MHD_gtls_asn2err (result);
2403 }
2404
2405 result = MHD__asn1_der_decoding (&c2, dist_points.data, dist_points.size, NULL);
2406 MHD__gnutls_free_datum (&dist_points);
2407
2408 if (result != ASN1_SUCCESS)
2409 {
2410 MHD_gnutls_assert ();
2411 MHD__asn1_delete_structure (&c2);
2412 return MHD_gtls_asn2err (result);
2413 }
2414
2415 /* Return the different names from the first CRLDistr. point.
2416 * The whole thing is a mess.
2417 */
2418 MHD_gtls_str_cpy (name, sizeof (name), "?1.distributionPoint.fullName");
2419
2420 result = parse_general_name (c2, name, seq, ret, ret_size, NULL, 0);
2421 if (result < 0)
2422 {
2423 MHD__asn1_delete_structure (&c2);
2424 return result;
2425 }
2426
2427 type = result;
2428
2429 /* Read the CRL reasons.
2430 */
2431 if (reason_flags)
2432 {
2433 MHD_gtls_str_cpy (name, sizeof (name), "?1.reasons");
2434
2435 reasons[0] = reasons[1] = 0;
2436
2437 len = sizeof (reasons);
2438 result = MHD__asn1_read_value (c2, name, reasons, &len);
2439
2440 if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS)
2441 {
2442 MHD_gnutls_assert ();
2443 MHD__asn1_delete_structure (&c2);
2444 return MHD_gtls_asn2err (result);
2445 }
2446
2447 *reason_flags = reasons[0] | (reasons[1] << 8);
2448 }
2449
2450 return type;
2451}
2452
2453/**
2454 * MHD_gnutls_x509_crt_get_key_purpose_oid - This function returns the Certificate's key purpose OIDs
2455 * @cert: should contain a MHD_gnutls_x509_crt_t structure
2456 * @indx: This specifies which OID to return. Use zero to get the first one.
2457 * @oid: a pointer to a buffer to hold the OID (may be null)
2458 * @sizeof_oid: initially holds the size of @oid
2459 *
2460 * This function will extract the key purpose OIDs of the Certificate
2461 * specified by the given index. These are stored in the Extended Key
2462 * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
2463 * human readable names.
2464 *
2465 * If @oid is null then only the size will be filled.
2466 *
2467 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2468 * not long enough, and in that case the *sizeof_oid will be updated
2469 * with the required size. On success 0 is returned.
2470 **/
2471int
2472MHD_gnutls_x509_crt_get_key_purpose_oid (MHD_gnutls_x509_crt_t cert,
2473 int indx,
2474 void *oid,
2475 size_t * sizeof_oid,
2476 unsigned int *critical)
2477{
2478 char tmpstr[MAX_NAME_SIZE];
2479 int result, len;
2480 MHD_gnutls_datum_t id;
2481 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2482
2483 if (cert == NULL)
2484 {
2485 MHD_gnutls_assert ();
2486 return GNUTLS_E_INVALID_REQUEST;
2487 }
2488
2489 if (oid)
2490 memset (oid, 0, *sizeof_oid);
2491 else
2492 *sizeof_oid = 0;
2493
2494 if ((result = MHD__gnutls_x509_crt_get_extension (cert, "2.5.29.37", 0, &id,
2495 critical)) < 0)
2496 {
2497 return result;
2498 }
2499
2500 if (id.size == 0 || id.data == NULL)
2501 {
2502 MHD_gnutls_assert ();
2503 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2504 }
2505
2506 result =
2507 MHD__asn1_create_element (MHD__gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
2508 if (result != ASN1_SUCCESS)
2509 {
2510 MHD_gnutls_assert ();
2511 MHD__gnutls_free_datum (&id);
2512 return MHD_gtls_asn2err (result);
2513 }
2514
2515 result = MHD__asn1_der_decoding (&c2, id.data, id.size, NULL);
2516 MHD__gnutls_free_datum (&id);
2517
2518 if (result != ASN1_SUCCESS)
2519 {
2520 MHD_gnutls_assert ();
2521 MHD__asn1_delete_structure (&c2);
2522 return MHD_gtls_asn2err (result);
2523 }
2524
2525 indx++;
2526 /* create a string like "?1"
2527 */
2528 snprintf (tmpstr, sizeof (tmpstr), "?%u", indx);
2529
2530 len = *sizeof_oid;
2531 result = MHD__asn1_read_value (c2, tmpstr, oid, &len);
2532
2533 *sizeof_oid = len;
2534 MHD__asn1_delete_structure (&c2);
2535
2536 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
2537 {
2538 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2539 }
2540
2541 if (result != ASN1_SUCCESS)
2542 {
2543 MHD_gnutls_assert ();
2544 return MHD_gtls_asn2err (result);
2545 }
2546
2547 return 0;
2548
2549}
2550
2551/**
2552 * MHD_gnutls_x509_crt_get_pk_rsa_raw - This function will export the RSA public key
2553 * @crt: Holds the certificate
2554 * @m: will hold the modulus
2555 * @e: will hold the public exponent
2556 *
2557 * This function will export the RSA public key's parameters found in
2558 * the given structure. The new parameters will be allocated using
2559 * MHD_gnutls_malloc() and will be stored in the appropriate datum.
2560 *
2561 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
2562 **/
2563int
2564MHD_gnutls_x509_crt_get_pk_rsa_raw (MHD_gnutls_x509_crt_t crt,
2565 MHD_gnutls_datum_t * m, MHD_gnutls_datum_t * e)
2566{
2567 int ret;
2568 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
2569 int params_size = MAX_PUBLIC_PARAMS_SIZE;
2570 int i;
2571
2572 if (crt == NULL)
2573 {
2574 MHD_gnutls_assert ();
2575 return GNUTLS_E_INVALID_REQUEST;
2576 }
2577
2578 ret = MHD_gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2579 if (ret != MHD_GNUTLS_PK_RSA)
2580 {
2581 MHD_gnutls_assert ();
2582 return GNUTLS_E_INVALID_REQUEST;
2583 }
2584
2585 ret = MHD__gnutls_x509_crt_get_mpis (crt, params, &params_size);
2586 if (ret < 0)
2587 {
2588 MHD_gnutls_assert ();
2589 return ret;
2590 }
2591
2592 ret = MHD_gtls_mpi_dprint (m, params[0]);
2593 if (ret < 0)
2594 {
2595 MHD_gnutls_assert ();
2596 goto cleanup;
2597 }
2598
2599 ret = MHD_gtls_mpi_dprint (e, params[1]);
2600 if (ret < 0)
2601 {
2602 MHD_gnutls_assert ();
2603 MHD__gnutls_free_datum (m);
2604 goto cleanup;
2605 }
2606
2607 ret = 0;
2608
2609cleanup:for (i = 0; i < params_size; i++)
2610 {
2611 MHD_gtls_mpi_release (&params[i]);
2612 }
2613 return ret;
2614}
2615
2616/**
2617 * MHD_gnutls_x509_crt_get_pk_dsa_raw - This function will export the DSA public key
2618 * @crt: Holds the certificate
2619 * @p: will hold the p
2620 * @q: will hold the q
2621 * @g: will hold the g
2622 * @y: will hold the y
2623 *
2624 * This function will export the DSA public key's parameters found in
2625 * the given certificate. The new parameters will be allocated using
2626 * MHD_gnutls_malloc() and will be stored in the appropriate datum.
2627 *
2628 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
2629 **/
2630int
2631MHD_gnutls_x509_crt_get_pk_dsa_raw (MHD_gnutls_x509_crt_t crt,
2632 MHD_gnutls_datum_t * p,
2633 MHD_gnutls_datum_t * q,
2634 MHD_gnutls_datum_t * g, MHD_gnutls_datum_t * y)
2635{
2636 int ret;
2637 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
2638 int params_size = MAX_PUBLIC_PARAMS_SIZE;
2639 int i;
2640
2641 if (crt == NULL)
2642 {
2643 MHD_gnutls_assert ();
2644 return GNUTLS_E_INVALID_REQUEST;
2645 }
2646
2647 ret = MHD_gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2648
2649 ret = MHD__gnutls_x509_crt_get_mpis (crt, params, &params_size);
2650 if (ret < 0)
2651 {
2652 MHD_gnutls_assert ();
2653 return ret;
2654 }
2655
2656 /* P */
2657 ret = MHD_gtls_mpi_dprint (p, params[0]);
2658 if (ret < 0)
2659 {
2660 MHD_gnutls_assert ();
2661 goto cleanup;
2662 }
2663
2664 /* Q */
2665 ret = MHD_gtls_mpi_dprint (q, params[1]);
2666 if (ret < 0)
2667 {
2668 MHD_gnutls_assert ();
2669 MHD__gnutls_free_datum (p);
2670 goto cleanup;
2671 }
2672
2673 /* G */
2674 ret = MHD_gtls_mpi_dprint (g, params[2]);
2675 if (ret < 0)
2676 {
2677 MHD_gnutls_assert ();
2678 MHD__gnutls_free_datum (p);
2679 MHD__gnutls_free_datum (q);
2680 goto cleanup;
2681 }
2682
2683 /* Y */
2684 ret = MHD_gtls_mpi_dprint (y, params[3]);
2685 if (ret < 0)
2686 {
2687 MHD_gnutls_assert ();
2688 MHD__gnutls_free_datum (p);
2689 MHD__gnutls_free_datum (g);
2690 MHD__gnutls_free_datum (q);
2691 goto cleanup;
2692 }
2693
2694 ret = 0;
2695
2696cleanup:for (i = 0; i < params_size; i++)
2697 {
2698 MHD_gtls_mpi_release (&params[i]);
2699 }
2700 return ret;
2701
2702}
2703
2704#endif 1273#endif
2705 1274
2706/**
2707 * MHD_gnutls_x509_crt_list_import - This function will import a PEM encoded certificate list
2708 * @certs: The structures to store the parsed certificate. Must not be initialized.
2709 * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
2710 * @data: The PEM encoded certificate.
2711 * @format: One of DER or PEM.
2712 * @flags: must be zero or an OR'd sequence of MHD_gnutls_certificate_import_flags.
2713 *
2714 * This function will convert the given PEM encoded certificate list
2715 * to the native MHD_gnutls_x509_crt_t format. The output will be stored
2716 * in @certs. They will be automatically initialized.
2717 *
2718 * If the Certificate is PEM encoded it should have a header of "X509
2719 * CERTIFICATE", or "CERTIFICATE".
2720 *
2721 * Returns: the number of certificates read or a negative error value.
2722 **/
2723int
2724MHD_gnutls_x509_crt_list_import (MHD_gnutls_x509_crt_t * certs,
2725 unsigned int *cert_max,
2726 const MHD_gnutls_datum_t * data,
2727 MHD_gnutls_x509_crt_fmt_t format, unsigned int flags)
2728{
2729 int size;
2730 const char *ptr;
2731 MHD_gnutls_datum_t tmp;
2732 int ret, nocopy = 0;
2733 unsigned int count = 0, j;
2734
2735 if (format == GNUTLS_X509_FMT_DER)
2736 {
2737 if (*cert_max < 1)
2738 {
2739 *cert_max = 1;
2740 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2741 }
2742
2743 count = 1; /* import only the first one */
2744
2745 ret = MHD_gnutls_x509_crt_init (&certs[0]);
2746 if (ret < 0)
2747 {
2748 MHD_gnutls_assert ();
2749 goto error;
2750 }
2751
2752 ret = MHD_gnutls_x509_crt_import (certs[0], data, format);
2753 if (ret < 0)
2754 {
2755 MHD_gnutls_assert ();
2756 goto error;
2757 }
2758
2759 *cert_max = 1;
2760 return 1;
2761 }
2762
2763 /* move to the certificate
2764 */
2765 ptr = MHD_memmem (data->data, data->size,
2766 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
2767 if (ptr == NULL)
2768 ptr = MHD_memmem (data->data, data->size,
2769 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
2770
2771 if (ptr == NULL)
2772 {
2773 MHD_gnutls_assert ();
2774 return GNUTLS_E_BASE64_DECODING_ERROR;
2775 }
2776 size = data->size - (ptr - (char *) data->data);
2777
2778 count = 0;
2779
2780 do
2781 {
2782 if (count >= *cert_max)
2783 {
2784 if (!(flags & GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
2785 break;
2786 else
2787 nocopy = 1;
2788 }
2789
2790 if (!nocopy)
2791 {
2792 ret = MHD_gnutls_x509_crt_init (&certs[count]);
2793 if (ret < 0)
2794 {
2795 MHD_gnutls_assert ();
2796 goto error;
2797 }
2798
2799 tmp.data = (void *) ptr;
2800 tmp.size = size;
2801
2802 ret =
2803 MHD_gnutls_x509_crt_import (certs[count], &tmp, GNUTLS_X509_FMT_PEM);
2804 if (ret < 0)
2805 {
2806 MHD_gnutls_assert ();
2807 goto error;
2808 }
2809 }
2810
2811 /* now we move ptr after the pem header
2812 */
2813 ptr++;
2814 /* find the next certificate (if any)
2815 */
2816 size = data->size - (ptr - (char *) data->data);
2817
2818 if (size > 0)
2819 {
2820 char *ptr2;
2821
2822 ptr2 = MHD_memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
2823 if (ptr2 == NULL)
2824 ptr2 =
2825 MHD_memmem (ptr, size, PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
2826
2827 ptr = ptr2;
2828 }
2829 else
2830 ptr = NULL;
2831
2832 count++;
2833 }
2834 while (ptr != NULL);
2835
2836 *cert_max = count;
2837
2838 if (nocopy == 0)
2839 return count;
2840 else
2841 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2842
2843error:for (j = 0; j < count; j++)
2844 MHD_gnutls_x509_crt_deinit (certs[j]);
2845 return ret;
2846}