xauthkid.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. /*
  5. * X.509 v3 Subject Key Usage Extension
  6. *
  7. */
  8. #include "prtypes.h"
  9. #include "seccomon.h"
  10. #include "secdert.h"
  11. #include "secoidt.h"
  12. #include "secasn1t.h"
  13. #include "secasn1.h"
  14. #include "secport.h"
  15. #include "certt.h"
  16. #include "genname.h"
  17. #include "secerr.h"
  18. SEC_ASN1_MKSUB(SEC_IntegerTemplate)
  19. SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
  20. const SEC_ASN1Template CERTAuthKeyIDTemplate[] = {
  21. { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTAuthKeyID) },
  22. { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
  23. offsetof(CERTAuthKeyID, keyID), SEC_ASN1_SUB(SEC_OctetStringTemplate) },
  24. { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
  25. offsetof(CERTAuthKeyID, DERAuthCertIssuer), CERT_GeneralNamesTemplate },
  26. { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2,
  27. offsetof(CERTAuthKeyID, authCertSerialNumber),
  28. SEC_ASN1_SUB(SEC_IntegerTemplate) },
  29. { 0 }
  30. };
  31. SECStatus
  32. CERT_EncodeAuthKeyID(PLArenaPool *arena, CERTAuthKeyID *value,
  33. SECItem *encodedValue)
  34. {
  35. SECStatus rv = SECFailure;
  36. PORT_Assert(value);
  37. PORT_Assert(arena);
  38. PORT_Assert(value->DERAuthCertIssuer == NULL);
  39. PORT_Assert(encodedValue);
  40. do {
  41. /* If both of the authCertIssuer and the serial number exist, encode
  42. the name first. Otherwise, it is an error if one exist and the other
  43. is not.
  44. */
  45. if (value->authCertIssuer) {
  46. if (!value->authCertSerialNumber.data) {
  47. PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
  48. break;
  49. }
  50. value->DERAuthCertIssuer =
  51. cert_EncodeGeneralNames(arena, value->authCertIssuer);
  52. if (!value->DERAuthCertIssuer) {
  53. PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
  54. break;
  55. }
  56. } else if (value->authCertSerialNumber.data) {
  57. PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
  58. break;
  59. }
  60. if (SEC_ASN1EncodeItem(arena, encodedValue, value,
  61. CERTAuthKeyIDTemplate) == NULL)
  62. break;
  63. rv = SECSuccess;
  64. } while (0);
  65. return (rv);
  66. }
  67. CERTAuthKeyID *
  68. CERT_DecodeAuthKeyID(PLArenaPool *arena, const SECItem *encodedValue)
  69. {
  70. CERTAuthKeyID *value = NULL;
  71. SECStatus rv = SECFailure;
  72. void *mark;
  73. SECItem newEncodedValue;
  74. PORT_Assert(arena);
  75. do {
  76. mark = PORT_ArenaMark(arena);
  77. value = (CERTAuthKeyID *)PORT_ArenaZAlloc(arena, sizeof(*value));
  78. if (value == NULL)
  79. break;
  80. value->DERAuthCertIssuer = NULL;
  81. /* copy the DER into the arena, since Quick DER returns data that points
  82. into the DER input, which may get freed by the caller */
  83. rv = SECITEM_CopyItem(arena, &newEncodedValue, encodedValue);
  84. if (rv != SECSuccess) {
  85. break;
  86. }
  87. rv = SEC_QuickDERDecodeItem(arena, value, CERTAuthKeyIDTemplate,
  88. &newEncodedValue);
  89. if (rv != SECSuccess)
  90. break;
  91. value->authCertIssuer =
  92. cert_DecodeGeneralNames(arena, value->DERAuthCertIssuer);
  93. if (value->authCertIssuer == NULL)
  94. break;
  95. /* what if the general name contains other format but not URI ?
  96. hl
  97. */
  98. if ((value->authCertSerialNumber.data && !value->authCertIssuer) ||
  99. (!value->authCertSerialNumber.data && value->authCertIssuer)) {
  100. PORT_SetError(SEC_ERROR_EXTENSION_VALUE_INVALID);
  101. break;
  102. }
  103. } while (0);
  104. if (rv != SECSuccess) {
  105. PORT_ArenaRelease(arena, mark);
  106. return ((CERTAuthKeyID *)NULL);
  107. }
  108. PORT_ArenaUnmark(arena, mark);
  109. return (value);
  110. }