PageRenderTime 66ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/x509/common.c

https://gitlab.com/axil/gnutls
C | 1852 lines | 1788 code | 25 blank | 39 comment | 23 complexity | de3e4e69543cc6c3336c6d0b47a364be MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. * Copyright (C) 2003-2014 Free Software Foundation, Inc.
  3. *
  4. * Author: Nikos Mavrogiannopoulos
  5. *
  6. * This file is part of GnuTLS.
  7. *
  8. * The GnuTLS is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * as published by the Free Software Foundation; either version 2.1 of
  11. * the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>
  20. *
  21. */
  22. #include <gnutls_int.h>
  23. #include <libtasn1.h>
  24. #include <gnutls_datum.h>
  25. #include <gnutls_global.h>
  26. #include <gnutls_errors.h>
  27. #include <gnutls_str.h>
  28. #include <gnutls_x509.h>
  29. #include <gnutls_num.h>
  30. #include <x509_b64.h>
  31. #include "x509_int.h"
  32. #include <common.h>
  33. #include <c-ctype.h>
  34. static int
  35. data2hex(const void *data, size_t data_size,
  36. void *_out, size_t * sizeof_out);
  37. struct oid_to_string {
  38. const char *oid;
  39. unsigned oid_size;
  40. const char *ldap_desc;
  41. unsigned ldap_desc_size;
  42. const char *asn_desc; /* description in the pkix file if complex type */
  43. unsigned int etype; /* the libtasn1 ASN1_ETYPE or INVALID
  44. * if cannot be simply parsed */
  45. };
  46. #define ENTRY(oid, ldap, asn, etype) {oid, sizeof(oid)-1, ldap, sizeof(ldap)-1, asn, etype}
  47. /* when there is no ldap description */
  48. #define ENTRY_ND(oid, asn, etype) {oid, sizeof(oid)-1, NULL, 0, asn, etype}
  49. /* This list contains all the OIDs that may be
  50. * contained in a rdnSequence and are printable.
  51. */
  52. static const struct oid_to_string _oid2str[] = {
  53. /* PKIX
  54. */
  55. ENTRY("1.3.6.1.5.5.7.9.2", "placeOfBirth", "PKIX1.DirectoryString",
  56. ASN1_ETYPE_INVALID),
  57. ENTRY("1.3.6.1.5.5.7.9.3", "gender", NULL, ASN1_ETYPE_PRINTABLE_STRING),
  58. ENTRY("1.3.6.1.5.5.7.9.4", "countryOfCitizenship", NULL,
  59. ASN1_ETYPE_PRINTABLE_STRING),
  60. ENTRY("1.3.6.1.5.5.7.9.5", "countryOfResidence", NULL,
  61. ASN1_ETYPE_PRINTABLE_STRING),
  62. ENTRY("2.5.4.6", "C", NULL, ASN1_ETYPE_PRINTABLE_STRING),
  63. ENTRY("2.5.4.9", "street", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
  64. ENTRY("2.5.4.12", "title", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
  65. ENTRY("2.5.4.10", "O", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
  66. ENTRY("2.5.4.11", "OU", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
  67. ENTRY("2.5.4.3", "CN", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
  68. ENTRY("2.5.4.7", "L", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
  69. ENTRY("2.5.4.8", "ST", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
  70. ENTRY("2.5.4.13", "description", "PKIX1.DirectoryString",
  71. ASN1_ETYPE_INVALID),
  72. ENTRY("2.5.4.5", "serialNumber", NULL, ASN1_ETYPE_PRINTABLE_STRING),
  73. ENTRY("2.5.4.20", "telephoneNumber", NULL, ASN1_ETYPE_PRINTABLE_STRING),
  74. ENTRY("2.5.4.4", "surName", "PKIX1.DirectoryString",
  75. ASN1_ETYPE_INVALID),
  76. ENTRY("2.5.4.43", "initials", "PKIX1.DirectoryString",
  77. ASN1_ETYPE_INVALID),
  78. ENTRY("2.5.4.44", "generationQualifier", "PKIX1.DirectoryString",
  79. ASN1_ETYPE_INVALID),
  80. ENTRY("2.5.4.42", "givenName", "PKIX1.DirectoryString",
  81. ASN1_ETYPE_INVALID),
  82. ENTRY("2.5.4.65", "pseudonym", "PKIX1.DirectoryString",
  83. ASN1_ETYPE_INVALID),
  84. ENTRY("2.5.4.46", "dnQualifier", NULL, ASN1_ETYPE_PRINTABLE_STRING),
  85. ENTRY("2.5.4.17", "postalCode", "PKIX1.DirectoryString",
  86. ASN1_ETYPE_INVALID),
  87. ENTRY("2.5.4.41", "name", "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
  88. ENTRY("2.5.4.15", "businessCategory", "PKIX1.DirectoryString",
  89. ASN1_ETYPE_INVALID),
  90. ENTRY("0.9.2342.19200300.100.1.25", "DC", NULL, ASN1_ETYPE_IA5_STRING),
  91. ENTRY("0.9.2342.19200300.100.1.1", "UID", "PKIX1.DirectoryString",
  92. ASN1_ETYPE_INVALID),
  93. ENTRY("1.2.840.113556.1.4.656", "userPrincipalName", "PKIX1.DirectoryString",
  94. ASN1_ETYPE_INVALID),
  95. /* Extended validation
  96. */
  97. ENTRY("1.3.6.1.4.1.311.60.2.1.1",
  98. "jurisdictionOfIncorporationLocalityName",
  99. "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
  100. ENTRY("1.3.6.1.4.1.311.60.2.1.2",
  101. "jurisdictionOfIncorporationStateOrProvinceName",
  102. "PKIX1.DirectoryString", ASN1_ETYPE_INVALID),
  103. ENTRY("1.3.6.1.4.1.311.60.2.1.3",
  104. "jurisdictionOfIncorporationCountryName",
  105. NULL, ASN1_ETYPE_PRINTABLE_STRING),
  106. /* PKCS #9
  107. */
  108. ENTRY("1.2.840.113549.1.9.1", "EMAIL", NULL, ASN1_ETYPE_IA5_STRING),
  109. ENTRY_ND("1.2.840.113549.1.9.7", "PKIX1.pkcs-9-challengePassword",
  110. ASN1_ETYPE_INVALID),
  111. /* friendly name */
  112. ENTRY_ND("1.2.840.113549.1.9.20", NULL, ASN1_ETYPE_BMP_STRING),
  113. /* local key id */
  114. ENTRY_ND("1.2.840.113549.1.9.21", NULL, ASN1_ETYPE_OCTET_STRING),
  115. /* rfc3920 section 5.1.1 */
  116. ENTRY("1.3.6.1.5.5.7.8.5", "XmppAddr", NULL, ASN1_ETYPE_UTF8_STRING),
  117. {NULL, 0, NULL, 0, NULL, 0}
  118. };
  119. static const struct oid_to_string *get_oid_entry(const char *oid)
  120. {
  121. unsigned int i = 0;
  122. unsigned len = strlen(oid);
  123. do {
  124. if (len == _oid2str[i].oid_size &&
  125. strcmp(_oid2str[i].oid, oid) == 0)
  126. return &_oid2str[i];
  127. i++;
  128. }
  129. while (_oid2str[i].oid != NULL);
  130. return NULL;
  131. }
  132. const char *_gnutls_ldap_string_to_oid(const char *str, unsigned str_len)
  133. {
  134. unsigned int i = 0;
  135. do {
  136. if ((_oid2str[i].ldap_desc != NULL) &&
  137. (str_len == _oid2str[i].ldap_desc_size) &&
  138. (strncasecmp(_oid2str[i].ldap_desc, str, str_len) ==
  139. 0))
  140. return _oid2str[i].oid;
  141. i++;
  142. }
  143. while (_oid2str[i].oid != NULL);
  144. return NULL;
  145. }
  146. /* Escapes a string following the rules from RFC4514.
  147. */
  148. static int str_escape(const gnutls_datum_t * str, gnutls_datum_t * escaped)
  149. {
  150. unsigned int j, i;
  151. uint8_t *buffer = NULL;
  152. int ret;
  153. if (str == NULL)
  154. return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
  155. /* the string will be at most twice the original */
  156. buffer = gnutls_malloc(str->size * 2 + 2);
  157. if (buffer == NULL)
  158. return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
  159. for (i = j = 0; i < str->size; i++) {
  160. if (str->data[i] == 0) {
  161. /* this is handled earlier */
  162. ret = gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
  163. goto cleanup;
  164. }
  165. if (str->data[i] == ',' || str->data[i] == '+'
  166. || str->data[i] == '"' || str->data[i] == '\\'
  167. || str->data[i] == '<' || str->data[i] == '>'
  168. || str->data[i] == ';' || str->data[i] == 0)
  169. buffer[j++] = '\\';
  170. else if (i == 0 && str->data[i] == '#')
  171. buffer[j++] = '\\';
  172. else if (i == 0 && str->data[i] == ' ')
  173. buffer[j++] = '\\';
  174. else if (i == (str->size - 1) && str->data[i] == ' ')
  175. buffer[j++] = '\\';
  176. buffer[j++] = str->data[i];
  177. }
  178. /* null terminate the string */
  179. buffer[j] = 0;
  180. escaped->data = buffer;
  181. escaped->size = j;
  182. return 0;
  183. cleanup:
  184. gnutls_free(buffer);
  185. return ret;
  186. }
  187. /**
  188. * gnutls_x509_dn_oid_known:
  189. * @oid: holds an Object Identifier in a null terminated string
  190. *
  191. * This function will inform about known DN OIDs. This is useful since
  192. * functions like gnutls_x509_crt_set_dn_by_oid() use the information
  193. * on known OIDs to properly encode their input. Object Identifiers
  194. * that are not known are not encoded by these functions, and their
  195. * input is stored directly into the ASN.1 structure. In that case of
  196. * unknown OIDs, you have the responsibility of DER encoding your
  197. * data.
  198. *
  199. * Returns: 1 on known OIDs and 0 otherwise.
  200. **/
  201. int gnutls_x509_dn_oid_known(const char *oid)
  202. {
  203. unsigned int i = 0;
  204. unsigned len = strlen(oid);
  205. do {
  206. if (len == _oid2str[i].oid_size &&
  207. strcmp(_oid2str[i].oid, oid) == 0)
  208. return 1;
  209. i++;
  210. }
  211. while (_oid2str[i].oid != NULL);
  212. return 0;
  213. }
  214. /**
  215. * gnutls_x509_dn_oid_name:
  216. * @oid: holds an Object Identifier in a null terminated string
  217. * @flags: 0 or GNUTLS_X509_DN_OID_*
  218. *
  219. * This function will return the name of a known DN OID. If
  220. * %GNUTLS_X509_DN_OID_RETURN_OID is specified this function
  221. * will return the given OID if no descriptive name has been
  222. * found.
  223. *
  224. * Returns: A null terminated string or NULL otherwise.
  225. *
  226. * Since: 3.0
  227. **/
  228. const char *gnutls_x509_dn_oid_name(const char *oid, unsigned int flags)
  229. {
  230. unsigned int i = 0;
  231. unsigned len = strlen(oid);
  232. do {
  233. if ((_oid2str[i].oid_size == len) &&
  234. strcmp(_oid2str[i].oid, oid) == 0 && _oid2str[i].ldap_desc != NULL)
  235. return _oid2str[i].ldap_desc;
  236. i++;
  237. }
  238. while (_oid2str[i].oid != NULL);
  239. if (flags & GNUTLS_X509_DN_OID_RETURN_OID)
  240. return oid;
  241. else
  242. return NULL;
  243. }
  244. static int
  245. make_printable_string(unsigned etype, const gnutls_datum_t * input,
  246. gnutls_datum_t * out)
  247. {
  248. int printable = 0;
  249. int ret;
  250. unsigned int i;
  251. size_t size;
  252. if (etype == ASN1_ETYPE_BMP_STRING) {
  253. ret = _gnutls_ucs2_to_utf8(input->data, input->size, out);
  254. if (ret < 0) {
  255. /* could not convert. Handle it as non-printable */
  256. printable = 0;
  257. } else
  258. printable = 1;
  259. } else if (etype == ASN1_ETYPE_TELETEX_STRING) {
  260. int ascii = 0;
  261. /* HACK: if the teletex string contains only ascii
  262. * characters then treat it as printable.
  263. */
  264. for (i = 0; i < input->size; i++)
  265. if (!c_isascii(input->data[i]))
  266. ascii = 1;
  267. if (ascii == 0) {
  268. out->data = gnutls_malloc(input->size + 1);
  269. if (out->data == NULL)
  270. return
  271. gnutls_assert_val
  272. (GNUTLS_E_MEMORY_ERROR);
  273. memcpy(out->data, input->data, input->size);
  274. out->size = input->size;
  275. out->data[out->size] = 0;
  276. printable = 1;
  277. }
  278. } else if (etype != ASN1_ETYPE_UNIVERSAL_STRING) /* supported but not printable */
  279. return GNUTLS_E_INVALID_REQUEST;
  280. if (printable == 0) { /* need to allocate out */
  281. out->size = input->size * 2 + 2;
  282. out->data = gnutls_malloc(out->size);
  283. if (out->data == NULL)
  284. return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
  285. size = out->size;
  286. ret = data2hex(input->data, input->size, out->data, &size);
  287. if (ret < 0) {
  288. gnutls_assert();
  289. goto cleanup;
  290. }
  291. out->size = size;
  292. }
  293. return 0;
  294. cleanup:
  295. _gnutls_free_datum(out);
  296. return ret;
  297. }
  298. static int
  299. decode_complex_string(const struct oid_to_string *oentry, void *value,
  300. int value_size, gnutls_datum_t * out)
  301. {
  302. char str[MAX_STRING_LEN], tmpname[128];
  303. int len = -1, result;
  304. ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
  305. char asn1_err[ASN1_MAX_ERROR_DESCRIPTION_SIZE] = "";
  306. unsigned int etype;
  307. gnutls_datum_t td;
  308. if (oentry->asn_desc == NULL) {
  309. gnutls_assert();
  310. return GNUTLS_E_INTERNAL_ERROR;
  311. }
  312. if ((result =
  313. asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc,
  314. &tmpasn)) != ASN1_SUCCESS) {
  315. gnutls_assert();
  316. return _gnutls_asn2err(result);
  317. }
  318. if ((result =
  319. asn1_der_decoding(&tmpasn, value, value_size,
  320. asn1_err)) != ASN1_SUCCESS) {
  321. gnutls_assert();
  322. _gnutls_debug_log("asn1_der_decoding: %s\n", asn1_err);
  323. asn1_delete_structure(&tmpasn);
  324. return _gnutls_asn2err(result);
  325. }
  326. /* Read the type of choice.
  327. */
  328. len = sizeof(str) - 1;
  329. if ((result = asn1_read_value(tmpasn, "", str, &len)) != ASN1_SUCCESS) { /* CHOICE */
  330. gnutls_assert();
  331. asn1_delete_structure(&tmpasn);
  332. return _gnutls_asn2err(result);
  333. }
  334. str[len] = 0;
  335. /* We set the etype on the strings that may need
  336. * some conversion to UTF-8. The INVALID flag indicates
  337. * no conversion needed */
  338. if (strcmp(str, "teletexString") == 0)
  339. etype = ASN1_ETYPE_TELETEX_STRING;
  340. else if (strcmp(str, "bmpString") == 0)
  341. etype = ASN1_ETYPE_BMP_STRING;
  342. else if (strcmp(str, "universalString") == 0)
  343. etype = ASN1_ETYPE_UNIVERSAL_STRING;
  344. else
  345. etype = ASN1_ETYPE_INVALID;
  346. _gnutls_str_cpy(tmpname, sizeof(tmpname), str);
  347. result = _gnutls_x509_read_value(tmpasn, tmpname, &td);
  348. asn1_delete_structure(&tmpasn);
  349. if (result < 0)
  350. return gnutls_assert_val(result);
  351. if (etype != ASN1_ETYPE_INVALID) {
  352. result = make_printable_string(etype, &td, out);
  353. _gnutls_free_datum(&td);
  354. if (result < 0)
  355. return gnutls_assert_val(result);
  356. } else {
  357. out->data = td.data;
  358. out->size = td.size;
  359. out->data[out->size] = 0;
  360. }
  361. /* Refuse to deal with strings containing NULs. */
  362. if (strlen((void *) out->data) != (size_t) out->size) {
  363. _gnutls_free_datum(out);
  364. return gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
  365. }
  366. return 0;
  367. }
  368. /* This function will convert an attribute value, specified by the OID,
  369. * to a string. The result will be a null terminated string.
  370. *
  371. * res may be null. This will just return the res_size, needed to
  372. * hold the string.
  373. */
  374. int
  375. _gnutls_x509_dn_to_string(const char *oid, void *value,
  376. int value_size, gnutls_datum_t * str)
  377. {
  378. const struct oid_to_string *oentry;
  379. int ret;
  380. gnutls_datum_t tmp;
  381. size_t size;
  382. if (value == NULL || value_size <= 0) {
  383. gnutls_assert();
  384. return GNUTLS_E_INVALID_REQUEST;
  385. }
  386. oentry = get_oid_entry(oid);
  387. if (oentry == NULL) { /* unknown OID -> hex */
  388. str->size = value_size * 2 + 2;
  389. str->data = gnutls_malloc(str->size);
  390. if (str->data == NULL)
  391. return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
  392. size = str->size;
  393. ret = data2hex(value, value_size, str->data, &size);
  394. if (ret < 0) {
  395. gnutls_assert();
  396. gnutls_free(str->data);
  397. return ret;
  398. }
  399. str->size = size;
  400. return 0;
  401. }
  402. if (oentry->asn_desc != NULL) { /* complex */
  403. ret =
  404. decode_complex_string(oentry, value, value_size, &tmp);
  405. if (ret < 0)
  406. return gnutls_assert_val(ret);
  407. } else {
  408. ret =
  409. _gnutls_x509_decode_string(oentry->etype, value,
  410. value_size, &tmp);
  411. if (ret < 0)
  412. return gnutls_assert_val(ret);
  413. }
  414. ret = str_escape(&tmp, str);
  415. _gnutls_free_datum(&tmp);
  416. if (ret < 0)
  417. return gnutls_assert_val(ret);
  418. return 0;
  419. }
  420. /* Converts a data string to an LDAP rfc2253 hex string
  421. * something like '#01020304'
  422. */
  423. static int
  424. data2hex(const void *data, size_t data_size,
  425. void *_out, size_t * sizeof_out)
  426. {
  427. char *res;
  428. char escaped[MAX_STRING_LEN];
  429. unsigned int size, res_size;
  430. char *out = _out;
  431. if (2 * data_size + 1 > MAX_STRING_LEN) {
  432. gnutls_assert();
  433. return GNUTLS_E_INTERNAL_ERROR;
  434. }
  435. res =
  436. _gnutls_bin2hex(data, data_size, escaped, sizeof(escaped),
  437. NULL);
  438. if (!res) {
  439. gnutls_assert();
  440. return GNUTLS_E_INTERNAL_ERROR;
  441. }
  442. res_size = strlen(res);
  443. size = res_size + 1; /* +1 for the '#' */
  444. if (size + 1 > *sizeof_out) {
  445. *sizeof_out = size + 1;
  446. return GNUTLS_E_SHORT_MEMORY_BUFFER;
  447. }
  448. *sizeof_out = size; /* -1 for the null +1 for the '#' */
  449. if (out) {
  450. out[0] = '#';
  451. memcpy(&out[1], res, res_size);
  452. out[size] = 0;
  453. }
  454. return 0;
  455. }
  456. /* TIME functions
  457. * Convertions between generalized or UTC time to time_t
  458. *
  459. */
  460. /* This is an emulations of the struct tm.
  461. * Since we do not use libc's functions, we don't need to
  462. * depend on the libc structure.
  463. */
  464. typedef struct fake_tm {
  465. int tm_mon;
  466. int tm_year; /* FULL year - ie 1971 */
  467. int tm_mday;
  468. int tm_hour;
  469. int tm_min;
  470. int tm_sec;
  471. } fake_tm;
  472. /* The mktime_utc function is due to Russ Allbery (rra@stanford.edu),
  473. * who placed it under public domain:
  474. */
  475. /* The number of days in each month.
  476. */
  477. static const int MONTHDAYS[] = {
  478. 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  479. };
  480. /* Whether a given year is a leap year. */
  481. #define ISLEAP(year) \
  482. (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
  483. /*
  484. ** Given a struct tm representing a calendar time in UTC, convert it to
  485. ** seconds since epoch. Returns (time_t) -1 if the time is not
  486. ** convertable. Note that this function does not canonicalize the provided
  487. ** struct tm, nor does it allow out of range values or years before 1970.
  488. */
  489. static time_t mktime_utc(const struct fake_tm *tm)
  490. {
  491. time_t result = 0;
  492. int i;
  493. /* We do allow some ill-formed dates, but we don't do anything special
  494. * with them and our callers really shouldn't pass them to us. Do
  495. * explicitly disallow the ones that would cause invalid array accesses
  496. * or other algorithm problems.
  497. */
  498. if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 1970)
  499. return (time_t) - 1;
  500. /* Convert to a time_t.
  501. */
  502. for (i = 1970; i < tm->tm_year; i++)
  503. result += 365 + ISLEAP(i);
  504. for (i = 0; i < tm->tm_mon; i++)
  505. result += MONTHDAYS[i];
  506. if (tm->tm_mon > 1 && ISLEAP(tm->tm_year))
  507. result++;
  508. result = 24 * (result + tm->tm_mday - 1) + tm->tm_hour;
  509. result = 60 * result + tm->tm_min;
  510. result = 60 * result + tm->tm_sec;
  511. return result;
  512. }
  513. /* this one will parse dates of the form:
  514. * month|day|hour|minute|sec* (2 chars each)
  515. * and year is given. Returns a time_t date.
  516. */
  517. static time_t time2gtime(const char *ttime, int year)
  518. {
  519. char xx[4];
  520. struct fake_tm etime;
  521. if (strlen(ttime) < 8) {
  522. gnutls_assert();
  523. return (time_t) - 1;
  524. }
  525. etime.tm_year = year;
  526. /* In order to work with 32 bit
  527. * time_t.
  528. */
  529. if (sizeof(time_t) <= 4 && etime.tm_year >= 2038)
  530. return (time_t) 2145914603; /* 2037-12-31 23:23:23 */
  531. if (etime.tm_year < 1970)
  532. return (time_t) 0;
  533. xx[2] = 0;
  534. /* get the month
  535. */
  536. memcpy(xx, ttime, 2); /* month */
  537. etime.tm_mon = atoi(xx) - 1;
  538. ttime += 2;
  539. /* get the day
  540. */
  541. memcpy(xx, ttime, 2); /* day */
  542. etime.tm_mday = atoi(xx);
  543. ttime += 2;
  544. /* get the hour
  545. */
  546. memcpy(xx, ttime, 2); /* hour */
  547. etime.tm_hour = atoi(xx);
  548. ttime += 2;
  549. /* get the minutes
  550. */
  551. memcpy(xx, ttime, 2); /* minutes */
  552. etime.tm_min = atoi(xx);
  553. ttime += 2;
  554. if (strlen(ttime) >= 2) {
  555. memcpy(xx, ttime, 2);
  556. etime.tm_sec = atoi(xx);
  557. } else
  558. etime.tm_sec = 0;
  559. return mktime_utc(&etime);
  560. }
  561. /* returns a time_t value that contains the given time.
  562. * The given time is expressed as:
  563. * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
  564. *
  565. * (seconds are optional)
  566. */
  567. static time_t utcTime2gtime(const char *ttime)
  568. {
  569. char xx[3];
  570. int year;
  571. if (strlen(ttime) < 10) {
  572. gnutls_assert();
  573. return (time_t) - 1;
  574. }
  575. xx[2] = 0;
  576. /* get the year
  577. */
  578. memcpy(xx, ttime, 2); /* year */
  579. year = atoi(xx);
  580. ttime += 2;
  581. if (year > 49)
  582. year += 1900;
  583. else
  584. year += 2000;
  585. return time2gtime(ttime, year);
  586. }
  587. /* returns a time_t value that contains the given time.
  588. * The given time is expressed as:
  589. * YEAR(4)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
  590. */
  591. time_t _gnutls_x509_generalTime2gtime(const char *ttime)
  592. {
  593. char xx[5];
  594. int year;
  595. if (strlen(ttime) < 12) {
  596. gnutls_assert();
  597. return (time_t) - 1;
  598. }
  599. if (strchr(ttime, 'Z') == 0) {
  600. gnutls_assert();
  601. /* sorry we don't support it yet
  602. */
  603. return (time_t) - 1;
  604. }
  605. xx[4] = 0;
  606. /* get the year
  607. */
  608. memcpy(xx, ttime, 4); /* year */
  609. year = atoi(xx);
  610. ttime += 4;
  611. return time2gtime(ttime, year);
  612. }
  613. static int
  614. gtime2generalTime(time_t gtime, char *str_time, size_t str_time_size)
  615. {
  616. size_t ret;
  617. struct tm _tm;
  618. if (gtime == (time_t)-1
  619. #if SIZEOF_LONG == 8
  620. || gtime >= 253402210800
  621. #endif
  622. ) {
  623. snprintf(str_time, str_time_size, "99991231235959Z");
  624. return 0;
  625. }
  626. if (!gmtime_r(&gtime, &_tm)) {
  627. gnutls_assert();
  628. return GNUTLS_E_INTERNAL_ERROR;
  629. }
  630. ret = strftime(str_time, str_time_size, "%Y%m%d%H%M%SZ", &_tm);
  631. if (!ret) {
  632. gnutls_assert();
  633. return GNUTLS_E_SHORT_MEMORY_BUFFER;
  634. }
  635. return 0;
  636. }
  637. /* Extracts the time in time_t from the ASN1_TYPE given. When should
  638. * be something like "tbsCertList.thisUpdate".
  639. */
  640. #define MAX_TIME 64
  641. time_t _gnutls_x509_get_time(ASN1_TYPE c2, const char *when, int nochoice)
  642. {
  643. char ttime[MAX_TIME];
  644. char name[128];
  645. time_t c_time = (time_t) - 1;
  646. int len, result;
  647. len = sizeof(ttime) - 1;
  648. result = asn1_read_value(c2, when, ttime, &len);
  649. if (result != ASN1_SUCCESS) {
  650. gnutls_assert();
  651. return (time_t) (-1);
  652. }
  653. if (nochoice != 0) {
  654. c_time = _gnutls_x509_generalTime2gtime(ttime);
  655. } else {
  656. _gnutls_str_cpy(name, sizeof(name), when);
  657. /* choice */
  658. if (strcmp(ttime, "generalTime") == 0) {
  659. _gnutls_str_cat(name, sizeof(name),
  660. ".generalTime");
  661. len = sizeof(ttime) - 1;
  662. result = asn1_read_value(c2, name, ttime, &len);
  663. if (result == ASN1_SUCCESS)
  664. c_time =
  665. _gnutls_x509_generalTime2gtime(ttime);
  666. } else { /* UTCTIME */
  667. _gnutls_str_cat(name, sizeof(name), ".utcTime");
  668. len = sizeof(ttime) - 1;
  669. result = asn1_read_value(c2, name, ttime, &len);
  670. if (result == ASN1_SUCCESS)
  671. c_time = utcTime2gtime(ttime);
  672. }
  673. /* We cannot handle dates after 2031 in 32 bit machines.
  674. * a time_t of 64bits has to be used.
  675. */
  676. if (result != ASN1_SUCCESS) {
  677. gnutls_assert();
  678. return (time_t) (-1);
  679. }
  680. }
  681. return c_time;
  682. }
  683. /* Sets the time in time_t in the ASN1_TYPE given. Where should
  684. * be something like "tbsCertList.thisUpdate".
  685. */
  686. int
  687. _gnutls_x509_set_time(ASN1_TYPE c2, const char *where, time_t tim,
  688. int nochoice)
  689. {
  690. char str_time[MAX_TIME];
  691. char name[128];
  692. int result, len;
  693. if (nochoice != 0) {
  694. result =
  695. gtime2generalTime(tim, str_time, sizeof(str_time));
  696. if (result < 0)
  697. return gnutls_assert_val(result);
  698. len = strlen(str_time);
  699. result = asn1_write_value(c2, where, str_time, len);
  700. if (result != ASN1_SUCCESS)
  701. return gnutls_assert_val(_gnutls_asn2err(result));
  702. return 0;
  703. }
  704. _gnutls_str_cpy(name, sizeof(name), where);
  705. if ((result = asn1_write_value(c2, name, "generalTime", 1)) < 0) {
  706. gnutls_assert();
  707. return _gnutls_asn2err(result);
  708. }
  709. result = gtime2generalTime(tim, str_time, sizeof(str_time));
  710. if (result < 0) {
  711. gnutls_assert();
  712. return result;
  713. }
  714. _gnutls_str_cat(name, sizeof(name), ".generalTime");
  715. len = strlen(str_time);
  716. result = asn1_write_value(c2, name, str_time, len);
  717. if (result != ASN1_SUCCESS) {
  718. gnutls_assert();
  719. return _gnutls_asn2err(result);
  720. }
  721. return 0;
  722. }
  723. gnutls_x509_subject_alt_name_t _gnutls_x509_san_find_type(char *str_type)
  724. {
  725. if (strcmp(str_type, "dNSName") == 0)
  726. return GNUTLS_SAN_DNSNAME;
  727. if (strcmp(str_type, "rfc822Name") == 0)
  728. return GNUTLS_SAN_RFC822NAME;
  729. if (strcmp(str_type, "uniformResourceIdentifier") == 0)
  730. return GNUTLS_SAN_URI;
  731. if (strcmp(str_type, "iPAddress") == 0)
  732. return GNUTLS_SAN_IPADDRESS;
  733. if (strcmp(str_type, "otherName") == 0)
  734. return GNUTLS_SAN_OTHERNAME;
  735. if (strcmp(str_type, "directoryName") == 0)
  736. return GNUTLS_SAN_DN;
  737. return (gnutls_x509_subject_alt_name_t) - 1;
  738. }
  739. /* A generic export function. Will export the given ASN.1 encoded data
  740. * to PEM or DER raw data.
  741. */
  742. int
  743. _gnutls_x509_export_int_named(ASN1_TYPE asn1_data, const char *name,
  744. gnutls_x509_crt_fmt_t format,
  745. const char *pem_header,
  746. unsigned char *output_data,
  747. size_t * output_data_size)
  748. {
  749. int ret;
  750. gnutls_datum_t out;
  751. size_t size;
  752. ret = _gnutls_x509_export_int_named2(asn1_data, name,
  753. format, pem_header, &out);
  754. if (ret < 0)
  755. return gnutls_assert_val(ret);
  756. if (format == GNUTLS_X509_FMT_PEM)
  757. size = out.size + 1;
  758. else
  759. size = out.size;
  760. if (*output_data_size < size) {
  761. *output_data_size = size;
  762. ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
  763. goto cleanup;
  764. }
  765. *output_data_size = (size_t) out.size;
  766. if (output_data) {
  767. memcpy(output_data, out.data, (size_t) out.size);
  768. if (format == GNUTLS_X509_FMT_PEM)
  769. output_data[out.size] = 0;
  770. }
  771. ret = 0;
  772. cleanup:
  773. gnutls_free(out.data);
  774. return ret;
  775. }
  776. /* A generic export function. Will export the given ASN.1 encoded data
  777. * to PEM or DER raw data.
  778. */
  779. int
  780. _gnutls_x509_export_int_named2(ASN1_TYPE asn1_data, const char *name,
  781. gnutls_x509_crt_fmt_t format,
  782. const char *pem_header,
  783. gnutls_datum_t * out)
  784. {
  785. int ret;
  786. if (format == GNUTLS_X509_FMT_DER) {
  787. ret = _gnutls_x509_der_encode(asn1_data, name, out, 0);
  788. if (ret < 0)
  789. return gnutls_assert_val(ret);
  790. } else { /* PEM */
  791. gnutls_datum_t tmp;
  792. ret = _gnutls_x509_der_encode(asn1_data, name, &tmp, 0);
  793. if (ret < 0)
  794. return gnutls_assert_val(ret);
  795. ret =
  796. _gnutls_fbase64_encode(pem_header, tmp.data, tmp.size,
  797. out);
  798. _gnutls_free_datum(&tmp);
  799. if (ret < 0)
  800. return gnutls_assert_val(ret);
  801. }
  802. return 0;
  803. }
  804. /* Decodes an octet string. The etype specifies the string type.
  805. * The returned string is always null terminated (but null is not
  806. * included in size).
  807. */
  808. int
  809. _gnutls_x509_decode_string(unsigned int etype,
  810. const uint8_t * der, size_t der_size,
  811. gnutls_datum_t * output)
  812. {
  813. int ret;
  814. const uint8_t *str;
  815. unsigned int str_size, len;
  816. gnutls_datum_t td;
  817. ret =
  818. asn1_decode_simple_der(etype, der, der_size, &str, &str_size);
  819. if (ret != ASN1_SUCCESS) {
  820. gnutls_assert();
  821. ret = _gnutls_asn2err(ret);
  822. return ret;
  823. }
  824. td.size = str_size;
  825. td.data = gnutls_malloc(str_size + 1);
  826. if (td.data == NULL)
  827. return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
  828. memcpy(td.data, str, str_size);
  829. td.data[str_size] = 0;
  830. ret = make_printable_string(etype, &td, output);
  831. if (ret == GNUTLS_E_INVALID_REQUEST) { /* unsupported etype */
  832. output->data = td.data;
  833. output->size = td.size;
  834. ret = 0;
  835. } else if (ret <= 0) {
  836. _gnutls_free_datum(&td);
  837. }
  838. /* Refuse to deal with strings containing NULs. */
  839. if (etype != ASN1_ETYPE_OCTET_STRING) {
  840. if (output->data)
  841. len = strlen((void *) output->data);
  842. else
  843. len = 0;
  844. if (len != (size_t) output->size) {
  845. _gnutls_free_datum(output);
  846. ret = gnutls_assert_val(GNUTLS_E_ASN1_DER_ERROR);
  847. }
  848. }
  849. return ret;
  850. }
  851. /* Reads a value from an ASN1 tree, and puts the output
  852. * in an allocated variable in the given datum.
  853. *
  854. * Note that this function always allocates one plus
  855. * the required data size (and places a null byte).
  856. */
  857. int
  858. _gnutls_x509_read_value(ASN1_TYPE c, const char *root,
  859. gnutls_datum_t * ret)
  860. {
  861. int len = 0, result;
  862. uint8_t *tmp = NULL;
  863. unsigned int etype;
  864. result = asn1_read_value_type(c, root, NULL, &len, &etype);
  865. if (result == 0 && len == 0) {
  866. ret->data = NULL;
  867. ret->size = 0;
  868. return 0;
  869. }
  870. if (result != ASN1_MEM_ERROR) {
  871. gnutls_assert();
  872. result = _gnutls_asn2err(result);
  873. return result;
  874. }
  875. if (etype == ASN1_ETYPE_BIT_STRING) {
  876. len = (len + 7)/8;
  877. }
  878. tmp = gnutls_malloc((size_t) len + 1);
  879. if (tmp == NULL) {
  880. gnutls_assert();
  881. result = GNUTLS_E_MEMORY_ERROR;
  882. goto cleanup;
  883. }
  884. result = asn1_read_value(c, root, tmp, &len);
  885. if (result != ASN1_SUCCESS) {
  886. gnutls_assert();
  887. result = _gnutls_asn2err(result);
  888. goto cleanup;
  889. }
  890. if (etype == ASN1_ETYPE_BIT_STRING) {
  891. ret->size = (len+7) / 8;
  892. } else
  893. ret->size = (unsigned) len;
  894. tmp[ret->size] = 0;
  895. ret->data = tmp;
  896. return 0;
  897. cleanup:
  898. gnutls_free(tmp);
  899. return result;
  900. }
  901. /* Reads a value from an ASN1 tree, then interprets it as the provided
  902. * type of string and returns the output in an allocated variable.
  903. *
  904. * Note that this function always places a null character
  905. * at the end of a readable string value (which is not accounted into size)
  906. */
  907. int
  908. _gnutls_x509_read_string(ASN1_TYPE c, const char *root,
  909. gnutls_datum_t * ret, unsigned int etype)
  910. {
  911. int len = 0, result;
  912. size_t slen;
  913. uint8_t *tmp = NULL;
  914. unsigned rtype;
  915. result = asn1_read_value_type(c, root, NULL, &len, &rtype);
  916. if (result != ASN1_MEM_ERROR) {
  917. gnutls_assert();
  918. result = _gnutls_asn2err(result);
  919. return result;
  920. }
  921. if (rtype == ASN1_ETYPE_BIT_STRING)
  922. len /= 8;
  923. tmp = gnutls_malloc((size_t) len + 1);
  924. if (tmp == NULL) {
  925. gnutls_assert();
  926. result = GNUTLS_E_MEMORY_ERROR;
  927. goto cleanup;
  928. }
  929. result = asn1_read_value(c, root, tmp, &len);
  930. if (result != ASN1_SUCCESS) {
  931. gnutls_assert();
  932. result = _gnutls_asn2err(result);
  933. goto cleanup;
  934. }
  935. if (rtype == ASN1_ETYPE_BIT_STRING)
  936. len /= 8;
  937. /* Extract the STRING.
  938. */
  939. slen = (size_t) len;
  940. result = _gnutls_x509_decode_string(etype, tmp, slen, ret);
  941. if (result < 0) {
  942. gnutls_assert();
  943. goto cleanup;
  944. }
  945. gnutls_free(tmp);
  946. return 0;
  947. cleanup:
  948. gnutls_free(tmp);
  949. return result;
  950. }
  951. /* The string type should be IA5String, UTF8String etc. Leave
  952. * null for octet string */
  953. int _gnutls_x509_encode_string(unsigned int etype,
  954. const void *input_data, size_t input_size,
  955. gnutls_datum_t * output)
  956. {
  957. uint8_t tl[ASN1_MAX_TL_SIZE];
  958. unsigned int tl_size;
  959. int ret;
  960. tl_size = sizeof(tl);
  961. ret =
  962. asn1_encode_simple_der(etype, input_data, input_size, tl,
  963. &tl_size);
  964. if (ret != ASN1_SUCCESS) {
  965. gnutls_assert();
  966. ret = _gnutls_asn2err(ret);
  967. return ret;
  968. }
  969. output->data = gnutls_malloc(tl_size + input_size);
  970. if (output->data == NULL)
  971. return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
  972. memcpy(output->data, tl, tl_size);
  973. memcpy(output->data + tl_size, input_data, input_size);
  974. output->size = tl_size + input_size;
  975. return 0;
  976. }
  977. /* DER Encodes the src ASN1_TYPE and stores it to
  978. * the given datum. If str is non zero then the data are encoded as
  979. * an OCTET STRING.
  980. */
  981. int
  982. _gnutls_x509_der_encode(ASN1_TYPE src, const char *src_name,
  983. gnutls_datum_t * res, int str)
  984. {
  985. int size, result;
  986. int asize;
  987. uint8_t *data = NULL;
  988. ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
  989. size = 0;
  990. result = asn1_der_coding(src, src_name, NULL, &size, NULL);
  991. if (result != ASN1_MEM_ERROR) {
  992. gnutls_assert();
  993. result = _gnutls_asn2err(result);
  994. goto cleanup;
  995. }
  996. /* allocate data for the der
  997. */
  998. if (str)
  999. size += 16; /* for later to include the octet tags */
  1000. asize = size;
  1001. data = gnutls_malloc((size_t) size);
  1002. if (data == NULL) {
  1003. gnutls_assert();
  1004. result = GNUTLS_E_MEMORY_ERROR;
  1005. goto cleanup;
  1006. }
  1007. result = asn1_der_coding(src, src_name, data, &size, NULL);
  1008. if (result != ASN1_SUCCESS) {
  1009. gnutls_assert();
  1010. result = _gnutls_asn2err(result);
  1011. goto cleanup;
  1012. }
  1013. if (str) {
  1014. if ((result = asn1_create_element
  1015. (_gnutls_get_pkix(), "PKIX1.pkcs-7-Data",
  1016. &c2)) != ASN1_SUCCESS) {
  1017. gnutls_assert();
  1018. result = _gnutls_asn2err(result);
  1019. goto cleanup;
  1020. }
  1021. result = asn1_write_value(c2, "", data, size);
  1022. if (result != ASN1_SUCCESS) {
  1023. gnutls_assert();
  1024. result = _gnutls_asn2err(result);
  1025. goto cleanup;
  1026. }
  1027. result = asn1_der_coding(c2, "", data, &asize, NULL);
  1028. if (result != ASN1_SUCCESS) {
  1029. gnutls_assert();
  1030. result = _gnutls_asn2err(result);
  1031. goto cleanup;
  1032. }
  1033. size = asize;
  1034. asn1_delete_structure(&c2);
  1035. }
  1036. res->data = data;
  1037. res->size = (unsigned) size;
  1038. return 0;
  1039. cleanup:
  1040. gnutls_free(data);
  1041. asn1_delete_structure(&c2);
  1042. return result;
  1043. }
  1044. /* DER Encodes the src ASN1_TYPE and stores it to
  1045. * dest in dest_name. Useful to encode something and store it
  1046. * as OCTET. If str is non null then the data are encoded as
  1047. * an OCTET STRING.
  1048. */
  1049. int
  1050. _gnutls_x509_der_encode_and_copy(ASN1_TYPE src, const char *src_name,
  1051. ASN1_TYPE dest, const char *dest_name,
  1052. int str)
  1053. {
  1054. int result;
  1055. gnutls_datum_t encoded;
  1056. result = _gnutls_x509_der_encode(src, src_name, &encoded, str);
  1057. if (result < 0) {
  1058. gnutls_assert();
  1059. return result;
  1060. }
  1061. /* Write the data.
  1062. */
  1063. result =
  1064. asn1_write_value(dest, dest_name, encoded.data,
  1065. (int) encoded.size);
  1066. _gnutls_free_datum(&encoded);
  1067. if (result != ASN1_SUCCESS) {
  1068. gnutls_assert();
  1069. return _gnutls_asn2err(result);
  1070. }
  1071. return 0;
  1072. }
  1073. /* Writes the value of the datum in the given ASN1_TYPE.
  1074. */
  1075. int
  1076. _gnutls_x509_write_value(ASN1_TYPE c, const char *root,
  1077. const gnutls_datum_t * data)
  1078. {
  1079. int ret;
  1080. /* Write the data.
  1081. */
  1082. ret = asn1_write_value(c, root, data->data, data->size);
  1083. if (ret != ASN1_SUCCESS) {
  1084. gnutls_assert();
  1085. return _gnutls_asn2err(ret);
  1086. }
  1087. return 0;
  1088. }
  1089. /* Writes the value of the datum in the given ASN1_TYPE as a string.
  1090. */
  1091. int
  1092. _gnutls_x509_write_string(ASN1_TYPE c, const char *root,
  1093. const gnutls_datum_t * data, unsigned int etype)
  1094. {
  1095. int ret;
  1096. gnutls_datum_t val = { NULL, 0 };
  1097. ret =
  1098. _gnutls_x509_encode_string(etype, data->data, data->size,
  1099. &val);
  1100. if (ret < 0)
  1101. return gnutls_assert_val(ret);
  1102. /* Write the data.
  1103. */
  1104. ret = asn1_write_value(c, root, val.data, val.size);
  1105. if (ret != ASN1_SUCCESS) {
  1106. gnutls_assert();
  1107. ret = _gnutls_asn2err(ret);
  1108. goto cleanup;
  1109. }
  1110. ret = 0;
  1111. cleanup:
  1112. _gnutls_free_datum(&val);
  1113. return ret;
  1114. }
  1115. void
  1116. _asnstr_append_name(char *name, size_t name_size, const char *part1,
  1117. const char *part2)
  1118. {
  1119. if (part1[0] != 0) {
  1120. _gnutls_str_cpy(name, name_size, part1);
  1121. _gnutls_str_cat(name, name_size, part2);
  1122. } else
  1123. _gnutls_str_cpy(name, name_size,
  1124. part2 + 1 /* remove initial dot */ );
  1125. }
  1126. /* Encodes and copies the private key parameters into a
  1127. * subjectPublicKeyInfo structure.
  1128. *
  1129. */
  1130. int
  1131. _gnutls_x509_encode_and_copy_PKI_params(ASN1_TYPE dst,
  1132. const char *dst_name,
  1133. gnutls_pk_algorithm_t
  1134. pk_algorithm,
  1135. gnutls_pk_params_st * params)
  1136. {
  1137. const char *pk;
  1138. gnutls_datum_t der = { NULL, 0 };
  1139. int result;
  1140. char name[128];
  1141. pk = _gnutls_x509_pk_to_oid(pk_algorithm);
  1142. if (pk == NULL) {
  1143. gnutls_assert();
  1144. return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
  1145. }
  1146. /* write the OID
  1147. */
  1148. _asnstr_append_name(name, sizeof(name), dst_name,
  1149. ".algorithm.algorithm");
  1150. result = asn1_write_value(dst, name, pk, 1);
  1151. if (result != ASN1_SUCCESS) {
  1152. gnutls_assert();
  1153. return _gnutls_asn2err(result);
  1154. }
  1155. result =
  1156. _gnutls_x509_write_pubkey_params(pk_algorithm, params, &der);
  1157. if (result < 0) {
  1158. gnutls_assert();
  1159. return result;
  1160. }
  1161. _asnstr_append_name(name, sizeof(name), dst_name,
  1162. ".algorithm.parameters");
  1163. result = asn1_write_value(dst, name, der.data, der.size);
  1164. _gnutls_free_datum(&der);
  1165. if (result != ASN1_SUCCESS) {
  1166. gnutls_assert();
  1167. return _gnutls_asn2err(result);
  1168. }
  1169. result = _gnutls_x509_write_pubkey(pk_algorithm, params, &der);
  1170. if (result < 0) {
  1171. gnutls_assert();
  1172. return result;
  1173. }
  1174. /* Write the DER parameters. (in bits)
  1175. */
  1176. _asnstr_append_name(name, sizeof(name), dst_name,
  1177. ".subjectPublicKey");
  1178. result = asn1_write_value(dst, name, der.data, der.size * 8);
  1179. _gnutls_free_datum(&der);
  1180. if (result != ASN1_SUCCESS) {
  1181. gnutls_assert();
  1182. return _gnutls_asn2err(result);
  1183. }
  1184. return 0;
  1185. }
  1186. /* Encodes and public key parameters into a
  1187. * subjectPublicKeyInfo structure and stores it in der.
  1188. */
  1189. int
  1190. _gnutls_x509_encode_PKI_params(gnutls_datum_t * der,
  1191. gnutls_pk_algorithm_t
  1192. pk_algorithm, gnutls_pk_params_st * params)
  1193. {
  1194. int ret;
  1195. ASN1_TYPE tmp;
  1196. ret = asn1_create_element(_gnutls_get_pkix(),
  1197. "PKIX1.Certificate", &tmp);
  1198. if (ret != ASN1_SUCCESS) {
  1199. gnutls_assert();
  1200. return _gnutls_asn2err(ret);
  1201. }
  1202. ret = _gnutls_x509_encode_and_copy_PKI_params(tmp,
  1203. "tbsCertificate.subjectPublicKeyInfo",
  1204. pk_algorithm,
  1205. params);
  1206. if (ret != ASN1_SUCCESS) {
  1207. gnutls_assert();
  1208. ret = _gnutls_asn2err(ret);
  1209. goto cleanup;
  1210. }
  1211. ret =
  1212. _gnutls_x509_der_encode(tmp,
  1213. "tbsCertificate.subjectPublicKeyInfo",
  1214. der, 0);
  1215. cleanup:
  1216. asn1_delete_structure(&tmp);
  1217. return ret;
  1218. }
  1219. /* Reads and returns the PK algorithm of the given certificate-like
  1220. * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
  1221. */
  1222. int
  1223. _gnutls_x509_get_pk_algorithm(ASN1_TYPE src, const char *src_name,
  1224. unsigned int *bits)
  1225. {
  1226. int result;
  1227. int algo;
  1228. char oid[64];
  1229. int len;
  1230. gnutls_pk_params_st params;
  1231. char name[128];
  1232. gnutls_pk_params_init(&params);
  1233. _asnstr_append_name(name, sizeof(name), src_name,
  1234. ".algorithm.algorithm");
  1235. len = sizeof(oid);
  1236. result = asn1_read_value(src, name, oid, &len);
  1237. if (result != ASN1_SUCCESS) {
  1238. gnutls_assert();
  1239. return _gnutls_asn2err(result);
  1240. }
  1241. algo = _gnutls_x509_oid2pk_algorithm(oid);
  1242. if (algo == GNUTLS_PK_UNKNOWN) {
  1243. _gnutls_debug_log
  1244. ("%s: unknown public key algorithm: %s\n", __func__,
  1245. oid);
  1246. }
  1247. if (bits == NULL) {
  1248. return algo;
  1249. }
  1250. /* Now read the parameters' bits
  1251. */
  1252. result = _gnutls_get_asn_mpis(src, src_name, &params);
  1253. if (result < 0)
  1254. return gnutls_assert_val(result);
  1255. bits[0] = pubkey_to_bits(algo, &params);
  1256. gnutls_pk_params_release(&params);
  1257. return algo;
  1258. }
  1259. /* Reads the DER signed data from the certificate and allocates space and
  1260. * returns them into signed_data.
  1261. */
  1262. int
  1263. _gnutls_x509_get_signed_data(ASN1_TYPE src, const char *src_name,
  1264. gnutls_datum_t * signed_data)
  1265. {
  1266. gnutls_datum_t der;
  1267. int start, end, result;
  1268. result = _gnutls_x509_der_encode(src, "", &der, 0);
  1269. if (result < 0) {
  1270. gnutls_assert();
  1271. return result;
  1272. }
  1273. /* Get the signed data
  1274. */
  1275. result = asn1_der_decoding_startEnd(src, der.data, der.size,
  1276. src_name, &start, &end);
  1277. if (result != ASN1_SUCCESS) {
  1278. result = _gnutls_asn2err(result);
  1279. gnutls_assert();
  1280. goto cleanup;
  1281. }
  1282. result =
  1283. _gnutls_set_datum(signed_data, &der.data[start],
  1284. end - start + 1);
  1285. if (result < 0) {
  1286. gnutls_assert();
  1287. goto cleanup;
  1288. }
  1289. result = 0;
  1290. cleanup:
  1291. _gnutls_free_datum(&der);
  1292. return result;
  1293. }
  1294. /*-
  1295. * gnutls_x509_get_signature_algorithm:
  1296. * @src: should contain an ASN1_TYPE structure
  1297. * @src_name: the description of the signature field
  1298. *
  1299. * This function will return a value of the #gnutls_sign_algorithm_t
  1300. * enumeration that is the signature algorithm that has been used to
  1301. * sign this certificate.
  1302. *
  1303. * Returns: a #gnutls_sign_algorithm_t value, or a negative error code on
  1304. * error.
  1305. -*/
  1306. int
  1307. _gnutls_x509_get_signature_algorithm(ASN1_TYPE src, const char *src_name)
  1308. {
  1309. int result;
  1310. gnutls_datum_t sa;
  1311. /* Read the signature algorithm. Note that parameters are not
  1312. * read. They will be read from the issuer's certificate if needed.
  1313. */
  1314. result = _gnutls_x509_read_value(src, src_name, &sa);
  1315. if (result < 0) {
  1316. gnutls_assert();
  1317. return result;
  1318. }
  1319. result = _gnutls_x509_oid2sign_algorithm((char *) sa.data);
  1320. _gnutls_free_datum(&sa);
  1321. return result;
  1322. }
  1323. /* Reads the DER signature from the certificate and allocates space and
  1324. * returns them into signed_data.
  1325. */
  1326. int
  1327. _gnutls_x509_get_signature(ASN1_TYPE src, const char *src_name,
  1328. gnutls_datum_t * signature)
  1329. {
  1330. int result, len;
  1331. unsigned int bits;
  1332. signature->data = NULL;
  1333. signature->size = 0;
  1334. /* Read the signature
  1335. */
  1336. len = 0;
  1337. result = asn1_read_value(src, src_name, NULL, &len);
  1338. if (result != ASN1_MEM_ERROR) {
  1339. result = _gnutls_asn2err(result);
  1340. gnutls_assert();
  1341. goto cleanup;
  1342. }
  1343. bits = len;
  1344. if (bits % 8 != 0) {
  1345. gnutls_assert();
  1346. result = GNUTLS_E_CERTIFICATE_ERROR;
  1347. goto cleanup;
  1348. }
  1349. len = bits / 8;
  1350. signature->data = gnutls_malloc(len);
  1351. if (signature->data == NULL) {
  1352. gnutls_assert();
  1353. result = GNUTLS_E_MEMORY_ERROR;
  1354. return result;
  1355. }
  1356. /* read the bit string of the signature
  1357. */
  1358. bits = len;
  1359. result =
  1360. asn1_read_value(src, src_name, signature->data, (int *) &bits);
  1361. if (result != ASN1_SUCCESS) {
  1362. result = _gnutls_asn2err(result);
  1363. gnutls_assert();
  1364. goto cleanup;
  1365. }
  1366. signature->size = len;
  1367. return 0;
  1368. cleanup:
  1369. return result;
  1370. }
  1371. /* ASN.1 PrintableString rules */
  1372. static int is_printable(char p)
  1373. {
  1374. if ((p >= 'a' && p <= 'z') || (p >= 'A' && p <= 'Z') ||
  1375. (p >= '0' && p <= '9') || p == ' ' || p == '(' || p == ')' ||
  1376. p == '+' || p == ',' || p == '-' || p == '.' || p == '/' ||
  1377. p == ':' || p == '=' || p == '?')
  1378. return 1;
  1379. return 0;
  1380. }
  1381. static int write_complex_string(ASN1_TYPE asn_struct, const char *where,
  1382. const struct oid_to_string *oentry,
  1383. const uint8_t * data, size_t data_size)
  1384. {
  1385. char tmp[128];
  1386. ASN1_TYPE c2;
  1387. int result;
  1388. const char *string_type;
  1389. unsigned int i;
  1390. result =
  1391. asn1_create_element(_gnutls_get_pkix(), oentry->asn_desc, &c2);
  1392. if (result != ASN1_SUCCESS) {
  1393. gnutls_assert();
  1394. return _gnutls_asn2err(result);
  1395. }
  1396. tmp[0] = 0;
  1397. string_type = "printableString";
  1398. /* Check if the data is ASN.1 printable, and use
  1399. * the UTF8 string type if not.
  1400. */
  1401. for (i = 0; i < data_size; i++) {
  1402. if (!is_printable(data[i])) {
  1403. string_type = "utf8String";
  1404. break;
  1405. }
  1406. }
  1407. /* if the type is a CHOICE then write the
  1408. * type we'll use.
  1409. */
  1410. result = asn1_write_value(c2, "", string_type, 1);
  1411. if (result != ASN1_SUCCESS) {
  1412. gnutls_assert();
  1413. result = _gnutls_asn2err(result);
  1414. goto error;
  1415. }
  1416. _gnutls_str_cpy(tmp, sizeof(tmp), string_type);
  1417. result = asn1_write_value(c2, tmp, data, data_size);
  1418. if (result != ASN1_SUCCESS) {
  1419. gnutls_assert();
  1420. result = _gnutls_asn2err(result);
  1421. goto error;
  1422. }
  1423. result =
  1424. _gnutls_x509_der_encode_and_copy(c2, "", asn_struct, where, 0);
  1425. if (result < 0) {
  1426. gnutls_assert();
  1427. goto error;
  1428. }
  1429. result = 0;
  1430. error:
  1431. asn1_delete_structure(&c2);
  1432. return result;
  1433. }
  1434. /* This will encode and write the AttributeTypeAndValue field.
  1435. * 'multi' must be (0) if writing an AttributeTypeAndValue, and 1 if Attribute.
  1436. * In all cases only one value is written.
  1437. */
  1438. int
  1439. _gnutls_x509_encode_and_write_attribute(const char *given_oid,
  1440. ASN1_TYPE asn1_struct,
  1441. const char *where,
  1442. const void *_data,
  1443. int data_size, int multi)
  1444. {
  1445. const uint8_t *data = _data;
  1446. char tmp[128];
  1447. int result;
  1448. const struct oid_to_string *oentry;
  1449. oentry = get_oid_entry(given_oid);
  1450. if (oentry == NULL) {
  1451. gnutls_assert();
  1452. _gnutls_debug_log("Cannot find OID: %s\n", given_oid);
  1453. return GNUTLS_E_X509_UNSUPPORTED_OID;
  1454. }
  1455. /* write the data (value)
  1456. */
  1457. _gnutls_str_cpy(tmp, sizeof(tmp), where);
  1458. _gnutls_str_cat(tmp, sizeof(tmp), ".value");
  1459. if (multi != 0) { /* if not writing an AttributeTypeAndValue, but an Attribute */
  1460. _gnutls_str_cat(tmp, sizeof(tmp), "s"); /* values */
  1461. result = asn1_write_value(asn1_struct, tmp, "NEW", 1);
  1462. if (result != ASN1_SUCCESS) {
  1463. gnutls_assert();
  1464. result = _gnutls_asn2err(result);
  1465. goto error;
  1466. }
  1467. _gnutls_str_cat(tmp, sizeof(tmp), ".?LAST");
  1468. }
  1469. if (oentry->asn_desc != NULL) { /* write a complex string API */
  1470. result =
  1471. write_complex_string(asn1_struct, tmp, oentry, data,
  1472. data_size);
  1473. if (result < 0)
  1474. return gnutls_assert_val(result);
  1475. } else { /* write a simple string */
  1476. gnutls_datum_t td;
  1477. td.data = (void *) data;
  1478. td.size = data_size;
  1479. result =
  1480. _gnutls_x509_write_string(asn1_struct, tmp, &td,
  1481. oentry->etype);
  1482. if (result < 0) {
  1483. gnutls_assert();
  1484. goto error;
  1485. }
  1486. }
  1487. /* write the type
  1488. */
  1489. _gnutls_str_cpy(tmp, sizeof(tmp), where);
  1490. _gnutls_str_cat(tmp, sizeof(tmp), ".type");
  1491. result = asn1_write_value(asn1_struct, tmp, given_oid, 1);
  1492. if (result != ASN1_SUCCESS) {
  1493. gnutls_assert();
  1494. result = _gnutls_asn2err(result);
  1495. goto error;
  1496. }
  1497. result = 0;
  1498. error:
  1499. return result;
  1500. }
  1501. /* copies a datum to a buffer. If it doesn't fit it returns
  1502. * GNUTLS_E_SHORT_MEMORY_BUFFER. It always deinitializes the datum
  1503. * after the copy.
  1504. *
  1505. * The buffer will always be null terminated.
  1506. */
  1507. int _gnutls_strdatum_to_buf(gnutls_datum_t * d, void *buf,
  1508. size_t * buf_size)
  1509. {
  1510. int ret;
  1511. uint8_t *_buf = buf;
  1512. if (buf == NULL || *buf_size < d->size + 1) {
  1513. *buf_size = d->size + 1;
  1514. ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
  1515. goto cleanup;
  1516. }
  1517. memcpy(buf, d->data, d->size);
  1518. _buf[d->size] = 0;
  1519. *buf_size = d->size;
  1520. ret = 0;
  1521. cleanup:
  1522. _gnutls_free_datum(d);
  1523. return ret;
  1524. }
  1525. int
  1526. _gnutls_x509_get_raw_dn2(ASN1_TYPE c2, gnutls_datum_t * raw,
  1527. const char *whom, gnutls_datum_t * dn)
  1528. {
  1529. int result, len1;
  1530. int start1, end1;
  1531. result =
  1532. asn1_der_decoding_startEnd(c2, raw->data, raw->size,
  1533. whom, &start1, &end1);
  1534. if (result != ASN1_SUCCESS) {
  1535. gnutls_assert();
  1536. result = _gnutls_asn2err(result);
  1537. goto cleanup;
  1538. }
  1539. len1 = end1 - start1 + 1;
  1540. result = _gnutls_set_datum(dn, &raw->data[start1], len1);
  1541. if (result < 0) {
  1542. gnutls_assert();
  1543. goto cleanup;
  1544. }
  1545. result = 0;
  1546. cleanup:
  1547. return result;
  1548. }