x509_cert_parser.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. /* X.509 certificate parser
  2. *
  3. * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public Licence
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the Licence, or (at your option) any later version.
  10. */
  11. #define pr_fmt(fmt) "X.509: "fmt
  12. #include <linux/kernel.h>
  13. #include <linux/export.h>
  14. #include <linux/slab.h>
  15. #include <linux/err.h>
  16. #include <linux/oid_registry.h>
  17. #include <crypto/public_key.h>
  18. #include "x509_parser.h"
  19. #include "x509-asn1.h"
  20. #include "x509_akid-asn1.h"
  21. struct x509_parse_context {
  22. struct x509_certificate *cert; /* Certificate being constructed */
  23. unsigned long data; /* Start of data */
  24. const void *cert_start; /* Start of cert content */
  25. const void *key; /* Key data */
  26. size_t key_size; /* Size of key data */
  27. enum OID last_oid; /* Last OID encountered */
  28. enum OID algo_oid; /* Algorithm OID */
  29. unsigned char nr_mpi; /* Number of MPIs stored */
  30. u8 o_size; /* Size of organizationName (O) */
  31. u8 cn_size; /* Size of commonName (CN) */
  32. u8 email_size; /* Size of emailAddress */
  33. u16 o_offset; /* Offset of organizationName (O) */
  34. u16 cn_offset; /* Offset of commonName (CN) */
  35. u16 email_offset; /* Offset of emailAddress */
  36. unsigned raw_akid_size;
  37. const void *raw_akid; /* Raw authorityKeyId in ASN.1 */
  38. const void *akid_raw_issuer; /* Raw directoryName in authorityKeyId */
  39. unsigned akid_raw_issuer_size;
  40. };
  41. /*
  42. * Free an X.509 certificate
  43. */
  44. void x509_free_certificate(struct x509_certificate *cert)
  45. {
  46. if (cert) {
  47. public_key_free(cert->pub);
  48. public_key_signature_free(cert->sig);
  49. kfree(cert->issuer);
  50. kfree(cert->subject);
  51. kfree(cert->id);
  52. kfree(cert->skid);
  53. kfree(cert);
  54. }
  55. }
  56. EXPORT_SYMBOL_GPL(x509_free_certificate);
  57. /*
  58. * Parse an X.509 certificate
  59. */
  60. struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
  61. {
  62. struct x509_certificate *cert;
  63. struct x509_parse_context *ctx;
  64. struct asymmetric_key_id *kid;
  65. long ret;
  66. ret = -ENOMEM;
  67. cert = kzalloc(sizeof(struct x509_certificate), GFP_KERNEL);
  68. if (!cert)
  69. goto error_no_cert;
  70. cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL);
  71. if (!cert->pub)
  72. goto error_no_ctx;
  73. cert->sig = kzalloc(sizeof(struct public_key_signature), GFP_KERNEL);
  74. if (!cert->sig)
  75. goto error_no_ctx;
  76. ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL);
  77. if (!ctx)
  78. goto error_no_ctx;
  79. ctx->cert = cert;
  80. ctx->data = (unsigned long)data;
  81. /* Attempt to decode the certificate */
  82. ret = asn1_ber_decoder(&x509_decoder, ctx, data, datalen);
  83. if (ret < 0)
  84. goto error_decode;
  85. /* Decode the AuthorityKeyIdentifier */
  86. if (ctx->raw_akid) {
  87. pr_devel("AKID: %u %*phN\n",
  88. ctx->raw_akid_size, ctx->raw_akid_size, ctx->raw_akid);
  89. ret = asn1_ber_decoder(&x509_akid_decoder, ctx,
  90. ctx->raw_akid, ctx->raw_akid_size);
  91. if (ret < 0) {
  92. pr_warn("Couldn't decode AuthKeyIdentifier\n");
  93. goto error_decode;
  94. }
  95. }
  96. ret = -ENOMEM;
  97. cert->pub->key = kmemdup(ctx->key, ctx->key_size, GFP_KERNEL);
  98. if (!cert->pub->key)
  99. goto error_decode;
  100. cert->pub->keylen = ctx->key_size;
  101. /* Grab the signature bits */
  102. ret = x509_get_sig_params(cert);
  103. if (ret < 0)
  104. goto error_decode;
  105. /* Generate cert issuer + serial number key ID */
  106. kid = asymmetric_key_generate_id(cert->raw_serial,
  107. cert->raw_serial_size,
  108. cert->raw_issuer,
  109. cert->raw_issuer_size);
  110. if (IS_ERR(kid)) {
  111. ret = PTR_ERR(kid);
  112. goto error_decode;
  113. }
  114. cert->id = kid;
  115. /* Detect self-signed certificates */
  116. ret = x509_check_for_self_signed(cert);
  117. if (ret < 0)
  118. goto error_decode;
  119. kfree(ctx);
  120. return cert;
  121. error_decode:
  122. kfree(ctx);
  123. error_no_ctx:
  124. x509_free_certificate(cert);
  125. error_no_cert:
  126. return ERR_PTR(ret);
  127. }
  128. EXPORT_SYMBOL_GPL(x509_cert_parse);
  129. /*
  130. * Note an OID when we find one for later processing when we know how
  131. * to interpret it.
  132. */
  133. int x509_note_OID(void *context, size_t hdrlen,
  134. unsigned char tag,
  135. const void *value, size_t vlen)
  136. {
  137. struct x509_parse_context *ctx = context;
  138. ctx->last_oid = look_up_OID(value, vlen);
  139. if (ctx->last_oid == OID__NR) {
  140. char buffer[50];
  141. sprint_oid(value, vlen, buffer, sizeof(buffer));
  142. pr_debug("Unknown OID: [%lu] %s\n",
  143. (unsigned long)value - ctx->data, buffer);
  144. }
  145. return 0;
  146. }
  147. /*
  148. * Save the position of the TBS data so that we can check the signature over it
  149. * later.
  150. */
  151. int x509_note_tbs_certificate(void *context, size_t hdrlen,
  152. unsigned char tag,
  153. const void *value, size_t vlen)
  154. {
  155. struct x509_parse_context *ctx = context;
  156. pr_debug("x509_note_tbs_certificate(,%zu,%02x,%ld,%zu)!\n",
  157. hdrlen, tag, (unsigned long)value - ctx->data, vlen);
  158. ctx->cert->tbs = value - hdrlen;
  159. ctx->cert->tbs_size = vlen + hdrlen;
  160. return 0;
  161. }
  162. /*
  163. * Record the public key algorithm
  164. */
  165. int x509_note_pkey_algo(void *context, size_t hdrlen,
  166. unsigned char tag,
  167. const void *value, size_t vlen)
  168. {
  169. struct x509_parse_context *ctx = context;
  170. pr_debug("PubKey Algo: %u\n", ctx->last_oid);
  171. switch (ctx->last_oid) {
  172. case OID_md2WithRSAEncryption:
  173. case OID_md3WithRSAEncryption:
  174. default:
  175. return -ENOPKG; /* Unsupported combination */
  176. case OID_md4WithRSAEncryption:
  177. ctx->cert->sig->hash_algo = "md4";
  178. ctx->cert->sig->pkey_algo = "rsa";
  179. break;
  180. case OID_sha1WithRSAEncryption:
  181. ctx->cert->sig->hash_algo = "sha1";
  182. ctx->cert->sig->pkey_algo = "rsa";
  183. break;
  184. case OID_sha256WithRSAEncryption:
  185. ctx->cert->sig->hash_algo = "sha256";
  186. ctx->cert->sig->pkey_algo = "rsa";
  187. break;
  188. case OID_sha384WithRSAEncryption:
  189. ctx->cert->sig->hash_algo = "sha384";
  190. ctx->cert->sig->pkey_algo = "rsa";
  191. break;
  192. case OID_sha512WithRSAEncryption:
  193. ctx->cert->sig->hash_algo = "sha512";
  194. ctx->cert->sig->pkey_algo = "rsa";
  195. break;
  196. case OID_sha224WithRSAEncryption:
  197. ctx->cert->sig->hash_algo = "sha224";
  198. ctx->cert->sig->pkey_algo = "rsa";
  199. break;
  200. }
  201. ctx->algo_oid = ctx->last_oid;
  202. return 0;
  203. }
  204. /*
  205. * Note the whereabouts and type of the signature.
  206. */
  207. int x509_note_signature(void *context, size_t hdrlen,
  208. unsigned char tag,
  209. const void *value, size_t vlen)
  210. {
  211. struct x509_parse_context *ctx = context;
  212. pr_debug("Signature type: %u size %zu\n", ctx->last_oid, vlen);
  213. if (ctx->last_oid != ctx->algo_oid) {
  214. pr_warn("Got cert with pkey (%u) and sig (%u) algorithm OIDs\n",
  215. ctx->algo_oid, ctx->last_oid);
  216. return -EINVAL;
  217. }
  218. if (strcmp(ctx->cert->sig->pkey_algo, "rsa") == 0) {
  219. /* Discard the BIT STRING metadata */
  220. if (vlen < 1 || *(const u8 *)value != 0)
  221. return -EBADMSG;
  222. value++;
  223. vlen--;
  224. }
  225. ctx->cert->raw_sig = value;
  226. ctx->cert->raw_sig_size = vlen;
  227. return 0;
  228. }
  229. /*
  230. * Note the certificate serial number
  231. */
  232. int x509_note_serial(void *context, size_t hdrlen,
  233. unsigned char tag,
  234. const void *value, size_t vlen)
  235. {
  236. struct x509_parse_context *ctx = context;
  237. ctx->cert->raw_serial = value;
  238. ctx->cert->raw_serial_size = vlen;
  239. return 0;
  240. }
  241. /*
  242. * Note some of the name segments from which we'll fabricate a name.
  243. */
  244. int x509_extract_name_segment(void *context, size_t hdrlen,
  245. unsigned char tag,
  246. const void *value, size_t vlen)
  247. {
  248. struct x509_parse_context *ctx = context;
  249. switch (ctx->last_oid) {
  250. case OID_commonName:
  251. ctx->cn_size = vlen;
  252. ctx->cn_offset = (unsigned long)value - ctx->data;
  253. break;
  254. case OID_organizationName:
  255. ctx->o_size = vlen;
  256. ctx->o_offset = (unsigned long)value - ctx->data;
  257. break;
  258. case OID_email_address:
  259. ctx->email_size = vlen;
  260. ctx->email_offset = (unsigned long)value - ctx->data;
  261. break;
  262. default:
  263. break;
  264. }
  265. return 0;
  266. }
  267. /*
  268. * Fabricate and save the issuer and subject names
  269. */
  270. static int x509_fabricate_name(struct x509_parse_context *ctx, size_t hdrlen,
  271. unsigned char tag,
  272. char **_name, size_t vlen)
  273. {
  274. const void *name, *data = (const void *)ctx->data;
  275. size_t namesize;
  276. char *buffer;
  277. if (*_name)
  278. return -EINVAL;
  279. /* Empty name string if no material */
  280. if (!ctx->cn_size && !ctx->o_size && !ctx->email_size) {
  281. buffer = kmalloc(1, GFP_KERNEL);
  282. if (!buffer)
  283. return -ENOMEM;
  284. buffer[0] = 0;
  285. goto done;
  286. }
  287. if (ctx->cn_size && ctx->o_size) {
  288. /* Consider combining O and CN, but use only the CN if it is
  289. * prefixed by the O, or a significant portion thereof.
  290. */
  291. namesize = ctx->cn_size;
  292. name = data + ctx->cn_offset;
  293. if (ctx->cn_size >= ctx->o_size &&
  294. memcmp(data + ctx->cn_offset, data + ctx->o_offset,
  295. ctx->o_size) == 0)
  296. goto single_component;
  297. if (ctx->cn_size >= 7 &&
  298. ctx->o_size >= 7 &&
  299. memcmp(data + ctx->cn_offset, data + ctx->o_offset, 7) == 0)
  300. goto single_component;
  301. buffer = kmalloc(ctx->o_size + 2 + ctx->cn_size + 1,
  302. GFP_KERNEL);
  303. if (!buffer)
  304. return -ENOMEM;
  305. memcpy(buffer,
  306. data + ctx->o_offset, ctx->o_size);
  307. buffer[ctx->o_size + 0] = ':';
  308. buffer[ctx->o_size + 1] = ' ';
  309. memcpy(buffer + ctx->o_size + 2,
  310. data + ctx->cn_offset, ctx->cn_size);
  311. buffer[ctx->o_size + 2 + ctx->cn_size] = 0;
  312. goto done;
  313. } else if (ctx->cn_size) {
  314. namesize = ctx->cn_size;
  315. name = data + ctx->cn_offset;
  316. } else if (ctx->o_size) {
  317. namesize = ctx->o_size;
  318. name = data + ctx->o_offset;
  319. } else {
  320. namesize = ctx->email_size;
  321. name = data + ctx->email_offset;
  322. }
  323. single_component:
  324. buffer = kmalloc(namesize + 1, GFP_KERNEL);
  325. if (!buffer)
  326. return -ENOMEM;
  327. memcpy(buffer, name, namesize);
  328. buffer[namesize] = 0;
  329. done:
  330. *_name = buffer;
  331. ctx->cn_size = 0;
  332. ctx->o_size = 0;
  333. ctx->email_size = 0;
  334. return 0;
  335. }
  336. int x509_note_issuer(void *context, size_t hdrlen,
  337. unsigned char tag,
  338. const void *value, size_t vlen)
  339. {
  340. struct x509_parse_context *ctx = context;
  341. ctx->cert->raw_issuer = value;
  342. ctx->cert->raw_issuer_size = vlen;
  343. return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen);
  344. }
  345. int x509_note_subject(void *context, size_t hdrlen,
  346. unsigned char tag,
  347. const void *value, size_t vlen)
  348. {
  349. struct x509_parse_context *ctx = context;
  350. ctx->cert->raw_subject = value;
  351. ctx->cert->raw_subject_size = vlen;
  352. return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->subject, vlen);
  353. }
  354. /*
  355. * Extract the data for the public key algorithm
  356. */
  357. int x509_extract_key_data(void *context, size_t hdrlen,
  358. unsigned char tag,
  359. const void *value, size_t vlen)
  360. {
  361. struct x509_parse_context *ctx = context;
  362. if (ctx->last_oid != OID_rsaEncryption)
  363. return -ENOPKG;
  364. ctx->cert->pub->pkey_algo = "rsa";
  365. /* Discard the BIT STRING metadata */
  366. if (vlen < 1 || *(const u8 *)value != 0)
  367. return -EBADMSG;
  368. ctx->key = value + 1;
  369. ctx->key_size = vlen - 1;
  370. return 0;
  371. }
  372. /* The keyIdentifier in AuthorityKeyIdentifier SEQUENCE is tag(CONT,PRIM,0) */
  373. #define SEQ_TAG_KEYID (ASN1_CONT << 6)
  374. /*
  375. * Process certificate extensions that are used to qualify the certificate.
  376. */
  377. int x509_process_extension(void *context, size_t hdrlen,
  378. unsigned char tag,
  379. const void *value, size_t vlen)
  380. {
  381. struct x509_parse_context *ctx = context;
  382. struct asymmetric_key_id *kid;
  383. const unsigned char *v = value;
  384. pr_debug("Extension: %u\n", ctx->last_oid);
  385. if (ctx->last_oid == OID_subjectKeyIdentifier) {
  386. /* Get hold of the key fingerprint */
  387. if (ctx->cert->skid || vlen < 3)
  388. return -EBADMSG;
  389. if (v[0] != ASN1_OTS || v[1] != vlen - 2)
  390. return -EBADMSG;
  391. v += 2;
  392. vlen -= 2;
  393. ctx->cert->raw_skid_size = vlen;
  394. ctx->cert->raw_skid = v;
  395. kid = asymmetric_key_generate_id(v, vlen, "", 0);
  396. if (IS_ERR(kid))
  397. return PTR_ERR(kid);
  398. ctx->cert->skid = kid;
  399. pr_debug("subjkeyid %*phN\n", kid->len, kid->data);
  400. return 0;
  401. }
  402. if (ctx->last_oid == OID_authorityKeyIdentifier) {
  403. /* Get hold of the CA key fingerprint */
  404. ctx->raw_akid = v;
  405. ctx->raw_akid_size = vlen;
  406. return 0;
  407. }
  408. return 0;
  409. }
  410. /**
  411. * x509_decode_time - Decode an X.509 time ASN.1 object
  412. * @_t: The time to fill in
  413. * @hdrlen: The length of the object header
  414. * @tag: The object tag
  415. * @value: The object value
  416. * @vlen: The size of the object value
  417. *
  418. * Decode an ASN.1 universal time or generalised time field into a struct the
  419. * kernel can handle and check it for validity. The time is decoded thus:
  420. *
  421. * [RFC5280 §4.1.2.5]
  422. * CAs conforming to this profile MUST always encode certificate validity
  423. * dates through the year 2049 as UTCTime; certificate validity dates in
  424. * 2050 or later MUST be encoded as GeneralizedTime. Conforming
  425. * applications MUST be able to process validity dates that are encoded in
  426. * either UTCTime or GeneralizedTime.
  427. */
  428. int x509_decode_time(time64_t *_t, size_t hdrlen,
  429. unsigned char tag,
  430. const unsigned char *value, size_t vlen)
  431. {
  432. static const unsigned char month_lengths[] = { 31, 28, 31, 30, 31, 30,
  433. 31, 31, 30, 31, 30, 31 };
  434. const unsigned char *p = value;
  435. unsigned year, mon, day, hour, min, sec, mon_len;
  436. #define dec2bin(X) ({ unsigned char x = (X) - '0'; if (x > 9) goto invalid_time; x; })
  437. #define DD2bin(P) ({ unsigned x = dec2bin(P[0]) * 10 + dec2bin(P[1]); P += 2; x; })
  438. if (tag == ASN1_UNITIM) {
  439. /* UTCTime: YYMMDDHHMMSSZ */
  440. if (vlen != 13)
  441. goto unsupported_time;
  442. year = DD2bin(p);
  443. if (year >= 50)
  444. year += 1900;
  445. else
  446. year += 2000;
  447. } else if (tag == ASN1_GENTIM) {
  448. /* GenTime: YYYYMMDDHHMMSSZ */
  449. if (vlen != 15)
  450. goto unsupported_time;
  451. year = DD2bin(p) * 100 + DD2bin(p);
  452. if (year >= 1950 && year <= 2049)
  453. goto invalid_time;
  454. } else {
  455. goto unsupported_time;
  456. }
  457. mon = DD2bin(p);
  458. day = DD2bin(p);
  459. hour = DD2bin(p);
  460. min = DD2bin(p);
  461. sec = DD2bin(p);
  462. if (*p != 'Z')
  463. goto unsupported_time;
  464. if (year < 1970 ||
  465. mon < 1 || mon > 12)
  466. goto invalid_time;
  467. mon_len = month_lengths[mon - 1];
  468. if (mon == 2) {
  469. if (year % 4 == 0) {
  470. mon_len = 29;
  471. if (year % 100 == 0) {
  472. mon_len = 28;
  473. if (year % 400 == 0)
  474. mon_len = 29;
  475. }
  476. }
  477. }
  478. if (day < 1 || day > mon_len ||
  479. hour > 24 || /* ISO 8601 permits 24:00:00 as midnight tomorrow */
  480. min > 59 ||
  481. sec > 60) /* ISO 8601 permits leap seconds [X.680 46.3] */
  482. goto invalid_time;
  483. *_t = mktime64(year, mon, day, hour, min, sec);
  484. return 0;
  485. unsupported_time:
  486. pr_debug("Got unsupported time [tag %02x]: '%*phN'\n",
  487. tag, (int)vlen, value);
  488. return -EBADMSG;
  489. invalid_time:
  490. pr_debug("Got invalid time [tag %02x]: '%*phN'\n",
  491. tag, (int)vlen, value);
  492. return -EBADMSG;
  493. }
  494. EXPORT_SYMBOL_GPL(x509_decode_time);
  495. int x509_note_not_before(void *context, size_t hdrlen,
  496. unsigned char tag,
  497. const void *value, size_t vlen)
  498. {
  499. struct x509_parse_context *ctx = context;
  500. return x509_decode_time(&ctx->cert->valid_from, hdrlen, tag, value, vlen);
  501. }
  502. int x509_note_not_after(void *context, size_t hdrlen,
  503. unsigned char tag,
  504. const void *value, size_t vlen)
  505. {
  506. struct x509_parse_context *ctx = context;
  507. return x509_decode_time(&ctx->cert->valid_to, hdrlen, tag, value, vlen);
  508. }
  509. /*
  510. * Note a key identifier-based AuthorityKeyIdentifier
  511. */
  512. int x509_akid_note_kid(void *context, size_t hdrlen,
  513. unsigned char tag,
  514. const void *value, size_t vlen)
  515. {
  516. struct x509_parse_context *ctx = context;
  517. struct asymmetric_key_id *kid;
  518. pr_debug("AKID: keyid: %*phN\n", (int)vlen, value);
  519. if (ctx->cert->sig->auth_ids[1])
  520. return 0;
  521. kid = asymmetric_key_generate_id(value, vlen, "", 0);
  522. if (IS_ERR(kid))
  523. return PTR_ERR(kid);
  524. pr_debug("authkeyid %*phN\n", kid->len, kid->data);
  525. ctx->cert->sig->auth_ids[1] = kid;
  526. return 0;
  527. }
  528. /*
  529. * Note a directoryName in an AuthorityKeyIdentifier
  530. */
  531. int x509_akid_note_name(void *context, size_t hdrlen,
  532. unsigned char tag,
  533. const void *value, size_t vlen)
  534. {
  535. struct x509_parse_context *ctx = context;
  536. pr_debug("AKID: name: %*phN\n", (int)vlen, value);
  537. ctx->akid_raw_issuer = value;
  538. ctx->akid_raw_issuer_size = vlen;
  539. return 0;
  540. }
  541. /*
  542. * Note a serial number in an AuthorityKeyIdentifier
  543. */
  544. int x509_akid_note_serial(void *context, size_t hdrlen,
  545. unsigned char tag,
  546. const void *value, size_t vlen)
  547. {
  548. struct x509_parse_context *ctx = context;
  549. struct asymmetric_key_id *kid;
  550. pr_debug("AKID: serial: %*phN\n", (int)vlen, value);
  551. if (!ctx->akid_raw_issuer || ctx->cert->sig->auth_ids[0])
  552. return 0;
  553. kid = asymmetric_key_generate_id(value,
  554. vlen,
  555. ctx->akid_raw_issuer,
  556. ctx->akid_raw_issuer_size);
  557. if (IS_ERR(kid))
  558. return PTR_ERR(kid);
  559. pr_debug("authkeyid %*phN\n", kid->len, kid->data);
  560. ctx->cert->sig->auth_ids[0] = kid;
  561. return 0;
  562. }