x_algor.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /*
  2. * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stddef.h>
  10. #include <openssl/x509.h>
  11. #include <openssl/asn1.h>
  12. #include <openssl/asn1t.h>
  13. #include <openssl/err.h>
  14. #include "crypto/asn1.h"
  15. #include "crypto/evp.h"
  16. ASN1_SEQUENCE(X509_ALGOR) = {
  17. ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
  18. ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
  19. } ASN1_SEQUENCE_END(X509_ALGOR)
  20. ASN1_ITEM_TEMPLATE(X509_ALGORS) =
  21. ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
  22. ASN1_ITEM_TEMPLATE_END(X509_ALGORS)
  23. IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR)
  24. IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS)
  25. IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR)
  26. int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
  27. {
  28. if (alg == NULL)
  29. return 0;
  30. if (ptype != V_ASN1_UNDEF && alg->parameter == NULL
  31. && (alg->parameter = ASN1_TYPE_new()) == NULL)
  32. return 0;
  33. ASN1_OBJECT_free(alg->algorithm);
  34. alg->algorithm = aobj;
  35. if (ptype == V_ASN1_EOC)
  36. return 1;
  37. if (ptype == V_ASN1_UNDEF) {
  38. ASN1_TYPE_free(alg->parameter);
  39. alg->parameter = NULL;
  40. } else
  41. ASN1_TYPE_set(alg->parameter, ptype, pval);
  42. return 1;
  43. }
  44. X509_ALGOR *ossl_X509_ALGOR_from_nid(int nid, int ptype, void *pval)
  45. {
  46. ASN1_OBJECT *algo = OBJ_nid2obj(nid);
  47. X509_ALGOR *alg = NULL;
  48. if (algo == NULL)
  49. return NULL;
  50. if ((alg = X509_ALGOR_new()) == NULL)
  51. goto err;
  52. if (X509_ALGOR_set0(alg, algo, ptype, pval))
  53. return alg;
  54. alg->algorithm = NULL; /* precaution to prevent double free */
  55. err:
  56. X509_ALGOR_free(alg);
  57. /* ASN1_OBJECT_free(algo) is not needed due to OBJ_nid2obj() */
  58. return NULL;
  59. }
  60. void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,
  61. const void **ppval, const X509_ALGOR *algor)
  62. {
  63. if (paobj)
  64. *paobj = algor->algorithm;
  65. if (pptype) {
  66. if (algor->parameter == NULL) {
  67. *pptype = V_ASN1_UNDEF;
  68. return;
  69. } else
  70. *pptype = algor->parameter->type;
  71. if (ppval)
  72. *ppval = algor->parameter->value.ptr;
  73. }
  74. }
  75. /* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
  76. void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
  77. {
  78. int type = md->flags & EVP_MD_FLAG_DIGALGID_ABSENT ? V_ASN1_UNDEF
  79. : V_ASN1_NULL;
  80. (void)X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_get_type(md)), type, NULL);
  81. }
  82. int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
  83. {
  84. int rv;
  85. rv = OBJ_cmp(a->algorithm, b->algorithm);
  86. if (rv)
  87. return rv;
  88. if (!a->parameter && !b->parameter)
  89. return 0;
  90. return ASN1_TYPE_cmp(a->parameter, b->parameter);
  91. }
  92. int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src)
  93. {
  94. if (src == NULL || dest == NULL)
  95. return 0;
  96. if (dest->algorithm)
  97. ASN1_OBJECT_free(dest->algorithm);
  98. dest->algorithm = NULL;
  99. if (dest->parameter)
  100. ASN1_TYPE_free(dest->parameter);
  101. dest->parameter = NULL;
  102. if (src->algorithm)
  103. if ((dest->algorithm = OBJ_dup(src->algorithm)) == NULL)
  104. return 0;
  105. if (src->parameter != NULL) {
  106. dest->parameter = ASN1_TYPE_new();
  107. if (dest->parameter == NULL)
  108. return 0;
  109. /* Assuming this is also correct for a BOOL.
  110. * set does copy as a side effect.
  111. */
  112. if (ASN1_TYPE_set1(dest->parameter, src->parameter->type,
  113. src->parameter->value.ptr) == 0)
  114. return 0;
  115. }
  116. return 1;
  117. }
  118. /* allocate and set algorithm ID from EVP_MD, default SHA1 */
  119. int ossl_x509_algor_new_from_md(X509_ALGOR **palg, const EVP_MD *md)
  120. {
  121. X509_ALGOR *alg;
  122. /* Default is SHA1 so no need to create it - still success */
  123. if (md == NULL || EVP_MD_is_a(md, "SHA1"))
  124. return 1;
  125. if ((alg = X509_ALGOR_new()) == NULL)
  126. return 0;
  127. X509_ALGOR_set_md(alg, md);
  128. *palg = alg;
  129. return 1;
  130. }
  131. /* convert algorithm ID to EVP_MD, default SHA1 */
  132. const EVP_MD *ossl_x509_algor_get_md(X509_ALGOR *alg)
  133. {
  134. const EVP_MD *md;
  135. if (alg == NULL)
  136. return EVP_sha1();
  137. md = EVP_get_digestbyobj(alg->algorithm);
  138. if (md == NULL)
  139. ERR_raise(ERR_LIB_ASN1, ASN1_R_UNKNOWN_DIGEST);
  140. return md;
  141. }
  142. X509_ALGOR *ossl_x509_algor_mgf1_decode(X509_ALGOR *alg)
  143. {
  144. if (OBJ_obj2nid(alg->algorithm) != NID_mgf1)
  145. return NULL;
  146. return ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(X509_ALGOR),
  147. alg->parameter);
  148. }
  149. /* Allocate and set MGF1 algorithm ID from EVP_MD */
  150. int ossl_x509_algor_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md)
  151. {
  152. X509_ALGOR *algtmp = NULL;
  153. ASN1_STRING *stmp = NULL;
  154. *palg = NULL;
  155. if (mgf1md == NULL || EVP_MD_is_a(mgf1md, "SHA1"))
  156. return 1;
  157. /* need to embed algorithm ID inside another */
  158. if (!ossl_x509_algor_new_from_md(&algtmp, mgf1md))
  159. goto err;
  160. if (ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp) == NULL)
  161. goto err;
  162. *palg = ossl_X509_ALGOR_from_nid(NID_mgf1, V_ASN1_SEQUENCE, stmp);
  163. if (*palg == NULL)
  164. goto err;
  165. stmp = NULL;
  166. err:
  167. ASN1_STRING_free(stmp);
  168. X509_ALGOR_free(algtmp);
  169. return *palg != NULL;
  170. }