1 /*! rsapem-1.2.0.js (c) 2012-2017 Kenji Urushima | kjur.github.com/jsrsasign/license 2 */ 3 /* 4 * rsapem.js - Cryptographic Algorithm Provider class 5 * 6 * Copyright (c) 2013-2017 Kenji Urushima (kenji.urushima@gmail.com) 7 * 8 * This software is licensed under the terms of the MIT License. 9 * http://kjur.github.com/jsrsasign/license 10 * 11 * The above copyright and license notice shall be 12 * included in all copies or substantial portions of the Software. 13 */ 14 15 /** 16 * @fileOverview 17 * @name rsapem-1.1.js 18 * @author Kenji Urushima kenji.urushima@gmail.com 19 * @version 1.2.0 (2017-Jan-21) 20 * @since jsrsasign 1.0 21 * @license <a href="http://kjur.github.io/jsrsasign/license/">MIT License</a> 22 */ 23 24 /** 25 * static method to extract Base64 string from PKCS#5 PEM RSA private key.<br/> 26 * @name pemToBase64 27 * @memberOf RSAKey 28 * @function 29 * @param {String} sPEMPrivateKey PEM PKCS#1/5 s private key string 30 * @return {String} Base64 string of private key 31 * @description 32 * removing PEM header, PEM footer and space characters including 33 * new lines from PEM formatted RSA private key string. 34 * @example 35 * RSAKey.pemToBase64("----BEGIN PRIVATE KEY-...") → "MIICW..." 36 */ 37 RSAKey.pemToBase64 = function(sPEMPrivateKey) { 38 var s = sPEMPrivateKey; 39 s = s.replace("-----BEGIN RSA PRIVATE KEY-----", ""); 40 s = s.replace("-----END RSA PRIVATE KEY-----", ""); 41 s = s.replace(/[ \n]+/g, ""); 42 return s; 43 }; 44 45 /** 46 * static method to get array of field positions from hexadecimal PKCS#5 RSA private key.<br/> 47 * @name getPosArrayOfChildrenFromHex 48 * @memberOf RSAKey 49 * @function 50 * @param {String} sPEMPrivateKey PEM PKCS#1/5 s private key string 51 * @return {Array} array of field positions 52 * @example 53 * RSAKey.getPosArrayOfChildrenFromHex("3082...") → [8, 32, ...] 54 */ 55 RSAKey.getPosArrayOfChildrenFromHex = function(hPrivateKey) { 56 var a = new Array(); 57 var idx_v = ASN1HEX.getStartPosOfV_AtObj(hPrivateKey, 0); 58 var idx_n = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, idx_v); 59 var idx_e = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, idx_n); 60 var idx_d = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, idx_e); 61 var idx_p = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, idx_d); 62 var idx_q = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, idx_p); 63 var idx_dp = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, idx_q); 64 var idx_dq = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, idx_dp); 65 var idx_co = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, idx_dq); 66 a.push(idx_v, idx_n, idx_e, idx_d, idx_p, idx_q, idx_dp, idx_dq, idx_co); 67 return a; 68 }; 69 70 /** 71 * static method to get array of hex field values from hexadecimal PKCS#5 RSA private key.<br/> 72 * @name getHexValueArrayOfChildrenFromHex 73 * @memberOf RSAKey 74 * @function 75 * @param {String} sPEMPrivateKey PEM PKCS#1/5 s private key string 76 * @return {Array} array of field hex value 77 * @example 78 * RSAKey.getHexValueArrayOfChildrenFromHex("3082...") → ["00", "3b42...", ...] 79 */ 80 RSAKey.getHexValueArrayOfChildrenFromHex = function(hPrivateKey) { 81 var posArray = RSAKey.getPosArrayOfChildrenFromHex(hPrivateKey); 82 var h_v = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[0]); 83 var h_n = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[1]); 84 var h_e = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[2]); 85 var h_d = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[3]); 86 var h_p = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[4]); 87 var h_q = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[5]); 88 var h_dp = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[6]); 89 var h_dq = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[7]); 90 var h_co = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[8]); 91 var a = new Array(); 92 a.push(h_v, h_n, h_e, h_d, h_p, h_q, h_dp, h_dq, h_co); 93 return a; 94 }; 95 96 /** 97 * read PKCS#1 private key from a string<br/> 98 * @name readPrivateKeyFromPEMString 99 * @memberOf RSAKey# 100 * @function 101 * @param {String} keyPEM string of PKCS#1 private key. 102 */ 103 RSAKey.prototype.readPrivateKeyFromPEMString = function(keyPEM) { 104 var keyB64 = RSAKey.pemToBase64(keyPEM); 105 var keyHex = b64tohex(keyB64) // depends base64.js 106 var a = RSAKey.getHexValueArrayOfChildrenFromHex(keyHex); 107 this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); 108 }; 109 110 /** 111 * (DEPRECATED) read RSA private key from a ASN.1 hexadecimal string<br/> 112 * @name readPrivateKeyFromASN1HexString 113 * @memberOf RSAKey# 114 * @function 115 * @param {String} keyHex ASN.1 hexadecimal string of PKCS#1 private key. 116 * @since rsapem 1.1.1 117 * @deprecated since jsrsasign 7.1.0 rsapem 1.2.0, please use {@link RSAKey.readPKCS5PrvKeyHex} instead. 118 */ 119 RSAKey.prototype.readPrivateKeyFromASN1HexString = function(keyHex) { 120 this.readPKCS5PrvKeyHex(keyHex); 121 }; 122 123 /** 124 * read an ASN.1 hexadecimal string of PKCS#1/5 plain RSA private key<br/> 125 * @name readPKCS5PrvKeyHex 126 * @memberOf RSAKey# 127 * @function 128 * @param {String} h hexadecimal string of PKCS#1/5 plain RSA private key 129 * @since jsrsasign 7.1.0 rsapem 1.2.0 130 * @see {@link RSAKey.readPrivateKeyFromASN1HexString} former method 131 */ 132 RSAKey.prototype.readPKCS5PrvKeyHex = function(h) { 133 var a = RSAKey.getHexValueArrayOfChildrenFromHex(h); 134 this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]); 135 }; 136 137 /** 138 * read an ASN.1 hexadecimal string of PKCS#8 plain RSA private key<br/> 139 * @name readPKCS8PrvKeyHex 140 * @memberOf RSAKey# 141 * @function 142 * @param {String} h hexadecimal string of PKCS#8 plain RSA private key 143 * @since jsrsasign 7.1.0 rsapem 1.2.0 144 */ 145 RSAKey.prototype.readPKCS8PrvKeyHex = function(h) { 146 var hN, hE, hD, hP, hQ, hDP, hDQ, hCO; 147 var _ASN1HEX = ASN1HEX; 148 var _getVbyList = _ASN1HEX.getVbyList; 149 150 if (_ASN1HEX.isASN1HEX(h) === false) 151 throw "not ASN.1 hex string"; 152 153 try { 154 hN = _getVbyList(h, 0, [2, 0, 1], "02"); 155 hE = _getVbyList(h, 0, [2, 0, 2], "02"); 156 hD = _getVbyList(h, 0, [2, 0, 3], "02"); 157 hP = _getVbyList(h, 0, [2, 0, 4], "02"); 158 hQ = _getVbyList(h, 0, [2, 0, 5], "02"); 159 hDP = _getVbyList(h, 0, [2, 0, 6], "02"); 160 hDQ = _getVbyList(h, 0, [2, 0, 7], "02"); 161 hCO = _getVbyList(h, 0, [2, 0, 8], "02"); 162 } catch(ex) { 163 throw "malformed PKCS#8 plain RSA private key"; 164 } 165 166 this.setPrivateEx(hN, hE, hD, hP, hQ, hDP, hDQ, hCO); 167 }; 168 169 /** 170 * read an ASN.1 hexadecimal string of PKCS#5 RSA public key<br/> 171 * @name readPKCS5PubKeyHex 172 * @memberOf RSAKey# 173 * @function 174 * @param {String} h hexadecimal string of PKCS#5 public key 175 * @since jsrsasign 7.1.0 rsapem 1.2.0 176 */ 177 RSAKey.prototype.readPKCS5PubKeyHex = function(h) { 178 if (ASN1HEX.isASN1HEX(h) === false) 179 throw "keyHex is not ASN.1 hex string"; 180 var aIdx = ASN1HEX.getPosArrayOfChildren_AtObj(h, 0); 181 if (aIdx.length !== 2 || 182 h.substr(aIdx[0], 2) !== "02" || 183 h.substr(aIdx[1], 2) !== "02") 184 throw "wrong hex for PKCS#5 public key"; 185 var hN = ASN1HEX.getHexOfV_AtObj(h, aIdx[0]); 186 var hE = ASN1HEX.getHexOfV_AtObj(h, aIdx[1]); 187 this.setPublic(hN, hE); 188 }; 189 190 /** 191 * read an ASN.1 hexadecimal string of PKCS#8 RSA public key<br/> 192 * @name readPKCS8PubKeyHex 193 * @memberOf RSAKey# 194 * @function 195 * @param {String} h hexadecimal string of PKCS#8 public key 196 * @since jsrsasign 7.1.0 rsapem 1.2.0 197 */ 198 RSAKey.prototype.readPKCS8PubKeyHex = function(h) { 199 if (ASN1HEX.isASN1HEX(h) === false) 200 throw "not ASN.1 hex string"; 201 202 // 06092a864886f70d010101: OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1) 203 if (ASN1HEX.getDecendantHexTLVByNthList(h, 0, [0, 0]) !== "06092a864886f70d010101") 204 throw "not PKCS8 RSA public key"; 205 206 var p5hex = ASN1HEX.getDecendantHexTLVByNthList(h, 0, [1, 0]); 207 this.readPKCS5PubKeyHex(p5hex); 208 }; 209 210 /** 211 * read an ASN.1 hexadecimal string of X.509 RSA public key certificate<br/> 212 * @name readCertPubKeyHex 213 * @memberOf RSAKey# 214 * @function 215 * @param {String} h hexadecimal string of X.509 RSA public key certificate 216 * @param {Integer} nthPKI nth index of publicKeyInfo. (DEFAULT: 6 for X509v3) 217 * @since jsrsasign 7.1.0 rsapem 1.2.0 218 */ 219 RSAKey.prototype.readCertPubKeyHex = function(h, nthPKI) { 220 if (nthPKI !== 5) nthPKI = 6; 221 if (ASN1HEX.isASN1HEX(h) === false) 222 throw "not ASN.1 hex string"; 223 224 var p8hex = ASN1HEX.getDecendantHexTLVByNthList(h, 0, [0, nthPKI]); 225 this.readPKCS8PubKeyHex(p8hex); 226 }; 227