4 * A class to parse some PEM stuff.
\r
5 * Copyright (c) 2007 Henri Torgemane
\r
7 * See LICENSE.txt for full license information.
\r
9 package com.hurlant.util.der
\r
11 import com.hurlant.crypto.rsa.RSAKey;
\r
12 import com.hurlant.math.BigInteger;
\r
13 import com.hurlant.util.Base64;
\r
15 import flash.utils.ByteArray;
\r
16 import com.hurlant.util.Hex;
\r
20 private static const RSA_PRIVATE_KEY_HEADER:String = "-----BEGIN RSA PRIVATE KEY-----";
\r
21 private static const RSA_PRIVATE_KEY_FOOTER:String = "-----END RSA PRIVATE KEY-----";
\r
22 private static const RSA_PUBLIC_KEY_HEADER:String = "-----BEGIN PUBLIC KEY-----";
\r
23 private static const RSA_PUBLIC_KEY_FOOTER:String = "-----END PUBLIC KEY-----";
\r
24 private static const CERTIFICATE_HEADER:String = "-----BEGIN CERTIFICATE-----";
\r
25 private static const CERTIFICATE_FOOTER:String = "-----END CERTIFICATE-----";
\r
31 * Read a structure encoded according to
\r
32 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
\r
39 public static function readRSAPrivateKey(str:String):RSAKey {
\r
40 var der:ByteArray = extractBinary(RSA_PRIVATE_KEY_HEADER, RSA_PRIVATE_KEY_FOOTER, str);
\r
41 if (der==null) return null;
\r
42 var obj:* = DER.parse(der);
\r
44 var arr:Array = obj as Array;
\r
45 // arr[0] is Version. should be 0. should be checked. shoulda woulda coulda.
\r
48 arr[2].valueOf(), // E
\r
63 * Read a structure encoded according to some spec somewhere
\r
64 * Also, follows some chunk from
\r
65 * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
\r
72 public static function readRSAPublicKey(str:String):RSAKey {
\r
73 var der:ByteArray = extractBinary(RSA_PUBLIC_KEY_HEADER, RSA_PUBLIC_KEY_FOOTER, str);
\r
74 if (der==null) return null;
\r
75 var obj:* = DER.parse(der);
\r
77 var arr:Array = obj as Array;
\r
78 // arr[0] = [ <some crap that means "rsaEncryption">, null ]; ( apparently, that's an X-509 Algorithm Identifier.
\r
79 if (arr[0][0].toString()!=OID.RSA_ENCRYPTION) {
\r
82 // arr[1] is a ByteArray begging to be parsed as DER
\r
83 arr[1].position = 1; // there's a 0x00 byte up front. find out why later. like, read a spec.
\r
84 obj = DER.parse(arr[1]);
\r
88 // arr[1] = public expt.
\r
89 return new RSAKey(arr[0], arr[1]);
\r
99 public static function readCertIntoArray(str:String):ByteArray {
\r
100 var tmp:ByteArray = extractBinary(CERTIFICATE_HEADER, CERTIFICATE_FOOTER, str);
\r
104 private static function extractBinary(header:String, footer:String, str:String):ByteArray {
\r
105 var i:int = str.indexOf(header);
\r
106 if (i==-1) return null;
\r
107 i += header.length;
\r
108 var j:int = str.indexOf(footer);
\r
109 if (j==-1) return null;
\r
110 var b64:String = str.substring(i, j);
\r
111 // remove whitesapces.
\r
112 b64 = b64.replace(/\s/mg, '');
\r
114 return Base64.decodeToByteArray(b64);
\r