Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

asn1.c 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation; either version 2 of the
  7. * License, or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #include <stdint.h>
  19. #include <stddef.h>
  20. #include <errno.h>
  21. #include <gpxe/asn1.h>
  22. /** @file
  23. *
  24. * ASN.1 encoding
  25. *
  26. */
  27. /**
  28. * Start parsing ASN.1 object
  29. *
  30. * @v cursor ASN.1 object cursor
  31. * @v type Expected type
  32. * @ret len Length of object body, or -1 on error
  33. *
  34. * The object cursor will be updated to point to the start of the
  35. * object body (i.e. the first byte following the length byte(s)), and
  36. * the length of the object body (i.e. the number of bytes until the
  37. * following object tag, if any) is returned.
  38. *
  39. * If any error occurs (i.e. if the object is not of the expected
  40. * type, or if we overflow beyond the end of the ASN.1 object), then
  41. * the cursor will be invalidated and a negative value will be
  42. * returned.
  43. */
  44. static int asn1_start_object ( struct asn1_cursor *cursor,
  45. unsigned int type ) {
  46. unsigned int len_len;
  47. unsigned int len;
  48. /* Sanity check */
  49. if ( cursor->len < 2 /* Tag byte and first length byte */ ) {
  50. if ( cursor->len )
  51. DBGC ( cursor, "ASN1 %p too short\n", cursor );
  52. goto notfound;
  53. }
  54. /* Check the tag byte */
  55. if ( cursor->data[0] != type ) {
  56. DBGC ( cursor, "ASN1 %p type mismatch (expected %d, got %d)\n",
  57. cursor, type, cursor->data[0] );
  58. goto notfound;
  59. }
  60. cursor->data++;
  61. cursor->len--;
  62. /* Extract length of the length field and sanity check */
  63. len_len = cursor->data[0];
  64. if ( len_len & 0x80 ) {
  65. len_len = ( len_len & 0x7f );
  66. cursor->data++;
  67. cursor->len--;
  68. } else {
  69. len_len = 1;
  70. }
  71. if ( cursor->len < len_len ) {
  72. DBGC ( cursor, "ASN1 %p bad length field length %d (max "
  73. "%zd)\n", cursor, len_len, cursor->len );
  74. goto notfound;
  75. }
  76. /* Extract the length and sanity check */
  77. for ( len = 0 ; len_len ; len_len-- ) {
  78. len <<= 8;
  79. len |= cursor->data[0];
  80. cursor->data++;
  81. cursor->len--;
  82. }
  83. if ( cursor->len < len ) {
  84. DBGC ( cursor, "ASN1 %p bad length %d (max %zd)\n",
  85. cursor, len, cursor->len );
  86. goto notfound;
  87. }
  88. return len;
  89. notfound:
  90. cursor->data = NULL;
  91. cursor->len = 0;
  92. return -1;
  93. }
  94. /**
  95. * Enter ASN.1 object
  96. *
  97. * @v cursor ASN.1 object cursor
  98. * @v type Expected type
  99. * @ret rc Return status code
  100. *
  101. * The object cursor will be updated to point to the body of the
  102. * current ASN.1 object. If any error occurs, the object cursor will
  103. * be invalidated.
  104. */
  105. int asn1_enter_object ( struct asn1_cursor *cursor, unsigned int type ) {
  106. int len;
  107. len = asn1_start_object ( cursor, type );
  108. if ( len < 0 )
  109. return -ENOENT;
  110. cursor->len = len;
  111. DBGC ( cursor, "ASN1 %p entered object type %02x (len %x)\n",
  112. cursor, type, len );
  113. return 0;
  114. }
  115. /**
  116. * Skip ASN.1 object
  117. *
  118. * @v cursor ASN.1 object cursor
  119. * @v type Expected type
  120. * @ret rc Return status code
  121. *
  122. * The object cursor will be updated to point to the next ASN.1
  123. * object. If any error occurs, the object cursor will be
  124. * invalidated.
  125. */
  126. int asn1_skip_object ( struct asn1_cursor *cursor, unsigned int type ) {
  127. int len;
  128. len = asn1_start_object ( cursor, type );
  129. if ( len < 0 )
  130. return -ENOENT;
  131. cursor->data += len;
  132. cursor->len -= len;
  133. DBGC ( cursor, "ASN1 %p skipped object type %02x (len %x)\n",
  134. cursor, type, len );
  135. if ( ! cursor->len ) {
  136. DBGC ( cursor, "ASN1 %p reached end of object\n", cursor );
  137. cursor->data = NULL;
  138. return -ENOENT;
  139. }
  140. return 0;
  141. }