1 /** 2 * --------- 3 * |.##> <##.| Open Smart Card Development Platform (www.openscdp.org) 4 * |# #| 5 * |# #| Copyright (c) 1999-2009 CardContact Software & System Consulting 6 * |'##> <##'| Andreas Schwier, 32429 Minden, Germany (www.cardcontact.de) 7 * --------- 8 * 9 * This file is part of OpenSCDP. 10 * 11 * OpenSCDP is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 * 15 * OpenSCDP is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with OpenSCDP; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 * 24 * @fileoverview Generate a set of test keys and save to GP profile 25 */ 26 27 28 load("tools/x509certificategenerator.js"); 29 30 31 /** 32 * Write key profile 33 * 34 * @param {String} filename the absolute file name to write the file to 35 * @param {XML} xml the structure to write 36 */ 37 function writeXML(filename, xml) { 38 print("Writing " + filename + "..."); 39 var fw = new java.io.FileWriter(filename); 40 fw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); 41 fw.write(xml.toXMLString()); 42 fw.close(); 43 } 44 45 46 47 /** 48 * Generate an ECC key pair on brainpoolP256r1 and save as GP key profile 49 * 50 * @param {String} name the name of the key 51 */ 52 function generateECCKeyPair(name) { 53 var curve = new ByteString("brainpoolP256r1", OID); 54 var keysize = 256; 55 56 var pubKey = new Key(); 57 pubKey.setType(Key.PUBLIC); 58 pubKey.setComponent(Key.ECC_CURVE_OID, curve); 59 60 var priKey = new Key(); 61 priKey.setType(Key.PRIVATE); 62 priKey.setComponent(Key.ECC_CURVE_OID, curve); 63 64 var crypto = new Crypto(); 65 crypto.generateKeyPair(Crypto.EC, pubKey, priKey); 66 67 var gp = new Namespace("http://namespaces.globalplatform.org/systems-profiles/1.1.0"); 68 69 var priKeyXML = 70 <gp:KeyProfile xmlns:gp={gp} UniqueID="2B0601040181C31F100006" ProfileVersion="1.1.0" ErrataVersion="0"> 71 <gp:Description>{"PrK_" + name + " ECDSA Private Key"}</gp:Description> 72 <gp:Revisions arrayElement="Revision" arrayIndex="#"> 73 <gp:Revision Version="1.0.0" Date="2011-11-11" Time="00:00:00" By="www.smartcard-hsm.org" Digest="00000000"/> 74 </gp:Revisions> 75 <gp:KeyInfo Name="ECPrivate" Type="PRIVATE" SubType="EC" Size={keysize} Mode="TEST"/> 76 <gp:Attribute Sensitive="false" Importable="true" Exportable="true"/> 77 <gp:Usage Encrypt="true" Decrypt="true" DecryptEncrypt="true" Sign="true" Verify="true" Wrap="true" Unwrap="true" UnwrapWrap="true" Derive="true"/> 78 <gp:Value Format="ECPRIVATE" arrayElement="Component" arrayIndex="#"> 79 <gp:Component Name="ECC_CURVE_OID" Encoding="HEX" Value={curve.toString(HEX)}></gp:Component> 80 <gp:Component Name="ECC_D" Encoding="HEX" Value={priKey.getComponent(Key.ECC_D).toString(HEX)}></gp:Component> 81 </gp:Value> 82 </gp:KeyProfile> 83 84 var pubKeyXML = 85 <gp:KeyProfile xmlns:gp={gp} UniqueID="2B0601040181C31F100008" ProfileVersion="1.1.0" ErrataVersion="0"> 86 <gp:Description>{"PuK_" + name + " ECDSA Public Key"}</gp:Description> 87 <gp:Revisions arrayElement="Revision" arrayIndex="#"> 88 <gp:Revision Version="1.0.0" Date="2011-11-11" Time="00:00:00" By="www.smartcard-hsm.org" Digest="00000000"/> 89 </gp:Revisions> 90 <gp:KeyInfo Name="ECPublic" Type="PUBLIC" SubType="EC" Size={keysize} Mode="TEST"/> 91 <gp:Attribute Sensitive="false" Importable="true" Exportable="true"/> 92 <gp:Usage Encrypt="true" Decrypt="true" DecryptEncrypt="true" Sign="true" Verify="true" Wrap="true" Unwrap="true" UnwrapWrap="true" Derive="true"/> 93 <gp:Value Format="ECPUBLIC" arrayElement="Component" arrayIndex="#"> 94 <gp:Component Name="ECC_CURVE_OID" Encoding="HEX" Value={curve.toString(HEX)}></gp:Component> 95 <gp:Component Name="ECC_QX" Encoding="HEX" Value={pubKey.getComponent(Key.ECC_QX).toString(HEX)}></gp:Component> 96 <gp:Component Name="ECC_QY" Encoding="HEX" Value={pubKey.getComponent(Key.ECC_QY).toString(HEX)}></gp:Component> 97 </gp:Value> 98 </gp:KeyProfile> 99 100 var fname = GPSystem.mapFilename("kp_prk_" + name + ".xml", GPSystem.CWD); 101 writeXML(fname, priKeyXML); 102 103 var fname = GPSystem.mapFilename("kp_puk_" + name + ".xml", GPSystem.CWD); 104 writeXML(fname, pubKeyXML); 105 } 106 107 108 109 /** 110 * Generate a sector key pair with the sector public key as PrK_Sector * PuK_Revocation 111 * 112 * @param {String} name the name of the key 113 */ 114 function generateSectorKeyPair(name) { 115 var curve = new ByteString("brainpoolP256r1", OID); 116 var keysize = 256; 117 118 var pubKey = new Key(); 119 pubKey.setType(Key.PUBLIC); 120 pubKey.setComponent(Key.ECC_CURVE_OID, curve); 121 122 var priKey = new Key(); 123 priKey.setType(Key.PRIVATE); 124 priKey.setComponent(Key.ECC_CURVE_OID, curve); 125 126 var crypto = new Crypto(); 127 crypto.generateKeyPair(Crypto.EC, pubKey, priKey); 128 129 var revocationKey = new Key("kp_puk_RevocationKey.xml"); 130 var inp = revocationKey.getComponent(Key.ECC_QX).concat(revocationKey.getComponent(Key.ECC_QY)); 131 var puk = crypto.decrypt(priKey, Crypto.ECDHP, inp); 132 var len = priKey.getComponent(Key.ECC_P).length; 133 pubKey.setComponent(Key.ECC_QX, puk.left(len)); 134 pubKey.setComponent(Key.ECC_QY, puk.right(len)); 135 136 var gp = new Namespace("http://namespaces.globalplatform.org/systems-profiles/1.1.0"); 137 138 var priKeyXML = 139 <gp:KeyProfile xmlns:gp={gp} UniqueID="2B0601040181C31F100006" ProfileVersion="1.1.0" ErrataVersion="0"> 140 <gp:Description>{"PrK_" + name + " ECDSA Private Key"}</gp:Description> 141 <gp:Revisions arrayElement="Revision" arrayIndex="#"> 142 <gp:Revision Version="1.0.0" Date="2011-11-11" Time="00:00:00" By="www.smartcard-hsm.org" Digest="00000000"/> 143 </gp:Revisions> 144 <gp:KeyInfo Name="ECPrivate" Type="PRIVATE" SubType="EC" Size={keysize} Mode="TEST"/> 145 <gp:Attribute Sensitive="false" Importable="true" Exportable="true"/> 146 <gp:Usage Encrypt="true" Decrypt="true" DecryptEncrypt="true" Sign="true" Verify="true" Wrap="true" Unwrap="true" UnwrapWrap="true" Derive="true"/> 147 <gp:Value Format="ECPRIVATE" arrayElement="Component" arrayIndex="#"> 148 <gp:Component Name="ECC_CURVE_OID" Encoding="HEX" Value={curve.toString(HEX)}></gp:Component> 149 <gp:Component Name="ECC_D" Encoding="HEX" Value={priKey.getComponent(Key.ECC_D).toString(HEX)}></gp:Component> 150 </gp:Value> 151 </gp:KeyProfile> 152 153 var pubKeyXML = 154 <gp:KeyProfile xmlns:gp={gp} UniqueID="2B0601040181C31F100008" ProfileVersion="1.1.0" ErrataVersion="0"> 155 <gp:Description>{"PuK_" + name + " ECDSA Public Key"}</gp:Description> 156 <gp:Revisions arrayElement="Revision" arrayIndex="#"> 157 <gp:Revision Version="1.0.0" Date="2011-11-11" Time="00:00:00" By="www.smartcard-hsm.org" Digest="00000000"/> 158 </gp:Revisions> 159 <gp:KeyInfo Name="ECPublic" Type="PUBLIC" SubType="EC" Size={keysize} Mode="TEST"/> 160 <gp:Attribute Sensitive="false" Importable="true" Exportable="true"/> 161 <gp:Usage Encrypt="true" Decrypt="true" DecryptEncrypt="true" Sign="true" Verify="true" Wrap="true" Unwrap="true" UnwrapWrap="true" Derive="true"/> 162 <gp:Value Format="ECPUBLIC" arrayElement="Component" arrayIndex="#"> 163 <gp:Component Name="ECC_CURVE_OID" Encoding="HEX" Value={curve.toString(HEX)}></gp:Component> 164 <gp:Component Name="ECC_QX" Encoding="HEX" Value={pubKey.getComponent(Key.ECC_QX).toString(HEX)}></gp:Component> 165 <gp:Component Name="ECC_QY" Encoding="HEX" Value={pubKey.getComponent(Key.ECC_QY).toString(HEX)}></gp:Component> 166 </gp:Value> 167 </gp:KeyProfile> 168 169 var fname = GPSystem.mapFilename("kp_prk_" + name + ".xml", GPSystem.CWD); 170 writeXML(fname, priKeyXML); 171 172 var fname = GPSystem.mapFilename("kp_puk_" + name + ".xml", GPSystem.CWD); 173 writeXML(fname, pubKeyXML); 174 } 175 176 177 178 generateECCKeyPair("GroupCAKey"); 179 generateECCKeyPair("UniqueCAKey"); 180 generateECCKeyPair("RevocationKey"); 181 generateSectorKeyPair("SectorKey1"); 182 generateSectorKeyPair("SectorKey2"); 183 generateECCKeyPair("IDKey