PageRenderTime 30ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/js/lib/Socket.IO-node/support/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/DER.as

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
ActionScript | 210 lines | 163 code | 7 blank | 40 comment | 26 complexity | 7c49472555df64190a7c902f7c6bb60e MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. /**
  2. * DER
  3. *
  4. * A basic class to parse DER structures.
  5. * It is very incomplete, but sufficient to extract whatever data we need so far.
  6. * Copyright (c) 2007 Henri Torgemane
  7. *
  8. * See LICENSE.txt for full license information.
  9. */
  10. package com.hurlant.util.der
  11. {
  12. import com.hurlant.math.BigInteger;
  13. import flash.utils.ByteArray;
  14. import com.hurlant.util.der.Sequence;
  15. import com.hurlant.util.Hex;
  16. // goal 1: to be able to parse an RSA Private Key PEM file.
  17. // goal 2: to parse an X509v3 cert. kinda.
  18. /**
  19. * DER for dummies:
  20. * http://luca.ntop.org/Teaching/Appunti/asn1.html
  21. *
  22. * This class does the bare minimum to get by. if that.
  23. */
  24. public class DER
  25. {
  26. public static var indent:String = "";
  27. public static function parse(der:ByteArray, structure:*=null):IAsn1Type {
  28. /* if (der.position==0) {
  29. trace("DER.parse: "+Hex.fromArray(der));
  30. }
  31. */ // type
  32. var type:int = der.readUnsignedByte();
  33. var constructed:Boolean = (type&0x20)!=0;
  34. type &=0x1F;
  35. // length
  36. var len:int = der.readUnsignedByte();
  37. if (len>=0x80) {
  38. // long form of length
  39. var count:int = len & 0x7f;
  40. len = 0;
  41. while (count>0) {
  42. len = (len<<8) | der.readUnsignedByte();
  43. count--;
  44. }
  45. }
  46. // data
  47. var b:ByteArray
  48. switch (type) {
  49. case 0x00: // WHAT IS THIS THINGY? (seen as 0xa0)
  50. // (note to self: read a spec someday.)
  51. // for now, treat as a sequence.
  52. case 0x10: // SEQUENCE/SEQUENCE OF. whatever
  53. // treat as an array
  54. var p:int = der.position;
  55. var o:Sequence = new Sequence(type, len);
  56. var arrayStruct:Array = structure as Array;
  57. if (arrayStruct!=null) {
  58. // copy the array, as we destroy it later.
  59. arrayStruct = arrayStruct.concat();
  60. }
  61. while (der.position < p+len) {
  62. var tmpStruct:Object = null
  63. if (arrayStruct!=null) {
  64. tmpStruct = arrayStruct.shift();
  65. }
  66. if (tmpStruct!=null) {
  67. while (tmpStruct && tmpStruct.optional) {
  68. // make sure we have something that looks reasonable. XXX I'm winging it here..
  69. var wantConstructed:Boolean = (tmpStruct.value is Array);
  70. var isConstructed:Boolean = isConstructedType(der);
  71. if (wantConstructed!=isConstructed) {
  72. // not found. put default stuff, or null
  73. o.push(tmpStruct.defaultValue);
  74. o[tmpStruct.name] = tmpStruct.defaultValue;
  75. // try the next thing
  76. tmpStruct = arrayStruct.shift();
  77. } else {
  78. break;
  79. }
  80. }
  81. }
  82. if (tmpStruct!=null) {
  83. var name:String = tmpStruct.name;
  84. var value:* = tmpStruct.value;
  85. if (tmpStruct.extract) {
  86. // we need to keep a binary copy of this element
  87. var size:int = getLengthOfNextElement(der);
  88. var ba:ByteArray = new ByteArray;
  89. ba.writeBytes(der, der.position, size);
  90. o[name+"_bin"] = ba;
  91. }
  92. var obj:IAsn1Type = DER.parse(der, value);
  93. o.push(obj);
  94. o[name] = obj;
  95. } else {
  96. o.push(DER.parse(der));
  97. }
  98. }
  99. return o;
  100. case 0x11: // SET/SET OF
  101. p = der.position;
  102. var s:Set = new Set(type, len);
  103. while (der.position < p+len) {
  104. s.push(DER.parse(der));
  105. }
  106. return s;
  107. case 0x02: // INTEGER
  108. // put in a BigInteger
  109. b = new ByteArray;
  110. der.readBytes(b,0,len);
  111. b.position=0;
  112. return new Integer(type, len, b);
  113. case 0x06: // OBJECT IDENTIFIER:
  114. b = new ByteArray;
  115. der.readBytes(b,0,len);
  116. b.position=0;
  117. return new ObjectIdentifier(type, len, b);
  118. default:
  119. trace("I DONT KNOW HOW TO HANDLE DER stuff of TYPE "+type);
  120. // fall through
  121. case 0x03: // BIT STRING
  122. if (der[der.position]==0) {
  123. //trace("Horrible Bit String pre-padding removal hack."); // I wish I had the patience to find a spec for this.
  124. der.position++;
  125. len--;
  126. }
  127. case 0x04: // OCTET STRING
  128. // stuff in a ByteArray for now.
  129. var bs:ByteString = new ByteString(type, len);
  130. der.readBytes(bs,0,len);
  131. return bs;
  132. case 0x05: // NULL
  133. // if len!=0, something's horribly wrong.
  134. // should I check?
  135. return null;
  136. case 0x13: // PrintableString
  137. var ps:PrintableString = new PrintableString(type, len);
  138. ps.setString(der.readMultiByte(len, "US-ASCII"));
  139. return ps;
  140. case 0x22: // XXX look up what this is. openssl uses this to store my email.
  141. case 0x14: // T61String - an horrible format we don't even pretend to support correctly
  142. ps = new PrintableString(type, len);
  143. ps.setString(der.readMultiByte(len, "latin1"));
  144. return ps;
  145. case 0x17: // UTCTime
  146. var ut:UTCTime = new UTCTime(type, len);
  147. ut.setUTCTime(der.readMultiByte(len, "US-ASCII"));
  148. return ut;
  149. }
  150. }
  151. private static function getLengthOfNextElement(b:ByteArray):int {
  152. var p:uint = b.position;
  153. // length
  154. b.position++;
  155. var len:int = b.readUnsignedByte();
  156. if (len>=0x80) {
  157. // long form of length
  158. var count:int = len & 0x7f;
  159. len = 0;
  160. while (count>0) {
  161. len = (len<<8) | b.readUnsignedByte();
  162. count--;
  163. }
  164. }
  165. len += b.position-p; // length of length
  166. b.position = p;
  167. return len;
  168. }
  169. private static function isConstructedType(b:ByteArray):Boolean {
  170. var type:int = b[b.position];
  171. return (type&0x20)!=0;
  172. }
  173. public static function wrapDER(type:int, data:ByteArray):ByteArray {
  174. var d:ByteArray = new ByteArray;
  175. d.writeByte(type);
  176. var len:int = data.length;
  177. if (len<128) {
  178. d.writeByte(len);
  179. } else if (len<256) {
  180. d.writeByte(1 | 0x80);
  181. d.writeByte(len);
  182. } else if (len<65536) {
  183. d.writeByte(2 | 0x80);
  184. d.writeByte(len>>8);
  185. d.writeByte(len);
  186. } else if (len<65536*256) {
  187. d.writeByte(3 | 0x80);
  188. d.writeByte(len>>16);
  189. d.writeByte(len>>8);
  190. d.writeByte(len);
  191. } else {
  192. d.writeByte(4 | 0x80);
  193. d.writeByte(len>>24);
  194. d.writeByte(len>>16);
  195. d.writeByte(len>>8);
  196. d.writeByte(len);
  197. }
  198. d.writeBytes(data);
  199. d.position=0;
  200. return d;
  201. }
  202. }
  203. }