secasn1u.c 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. * Utility routines to complement the ASN.1 encoding and decoding functions.
  6. */
  7. #include "secasn1.h"
  8. /*
  9. * We have a length that needs to be encoded; how many bytes will the
  10. * encoding take?
  11. *
  12. * The rules are that 0 - 0x7f takes one byte (the length itself is the
  13. * entire encoding); everything else takes one plus the number of bytes
  14. * in the length.
  15. */
  16. int
  17. SEC_ASN1LengthLength(unsigned long len)
  18. {
  19. int lenlen = 1;
  20. if (len > 0x7f) {
  21. do {
  22. lenlen++;
  23. len >>= 8;
  24. } while (len);
  25. }
  26. return lenlen;
  27. }
  28. /*
  29. * XXX Move over (and rewrite as appropriate) the rest of the
  30. * stuff in dersubr.c!
  31. */
  32. /*
  33. * Find the appropriate subtemplate for the given template.
  34. * This may involve calling a "chooser" function, or it may just
  35. * be right there. In either case, it is expected to *have* a
  36. * subtemplate; this is asserted in debug builds (in non-debug
  37. * builds, NULL will be returned).
  38. *
  39. * "thing" is a pointer to the structure being encoded/decoded
  40. * "encoding", when true, means that we are in the process of encoding
  41. * (as opposed to in the process of decoding)
  42. */
  43. const SEC_ASN1Template *
  44. SEC_ASN1GetSubtemplate(const SEC_ASN1Template *theTemplate, void *thing,
  45. PRBool encoding)
  46. {
  47. const SEC_ASN1Template *subt = NULL;
  48. PORT_Assert(theTemplate->sub != NULL);
  49. if (theTemplate->sub != NULL) {
  50. if (theTemplate->kind & SEC_ASN1_DYNAMIC) {
  51. SEC_ASN1TemplateChooserPtr chooserp;
  52. chooserp = *(SEC_ASN1TemplateChooserPtr *)theTemplate->sub;
  53. if (chooserp) {
  54. if (thing != NULL)
  55. thing = (char *)thing - theTemplate->offset;
  56. subt = (*chooserp)(thing, encoding);
  57. }
  58. } else {
  59. subt = (SEC_ASN1Template *)theTemplate->sub;
  60. }
  61. }
  62. return subt;
  63. }
  64. PRBool
  65. SEC_ASN1IsTemplateSimple(const SEC_ASN1Template *theTemplate)
  66. {
  67. if (!theTemplate) {
  68. return PR_TRUE; /* it doesn't get any simpler than NULL */
  69. }
  70. /* only templates made of one primitive type or a choice of primitive
  71. types are considered simple */
  72. if (!(theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK))) {
  73. return PR_TRUE; /* primitive type */
  74. }
  75. if (!(theTemplate->kind & SEC_ASN1_CHOICE)) {
  76. return PR_FALSE; /* no choice means not simple */
  77. }
  78. while (++theTemplate && theTemplate->kind) {
  79. if (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK)) {
  80. return PR_FALSE; /* complex type */
  81. }
  82. }
  83. return PR_TRUE; /* choice of primitive types */
  84. }