From 7228228d963bf59a5998fc226b52db180a84acbc Mon Sep 17 00:00:00 2001 From: Sean Colyer Date: Tue, 10 Apr 2012 22:04:29 -0400 Subject: [PATCH] Updates to work for s2k with AES encryption. Added numBytes to s2k reading with passphrase to account for s2k encryption with blocksize > hashsize output. --- resources/openpgp.js | 26 ++++++++++--- resources/openpgp.min.js | 48 ++++++++++++------------ src/packet/openpgp.packet.keymaterial.js | 20 ++++++++-- src/type/openpgp.type.s2k.js | 6 ++- 4 files changed, 66 insertions(+), 34 deletions(-) diff --git a/resources/openpgp.js b/resources/openpgp.js index c984929b..434d5f95 100644 --- a/resources/openpgp.js +++ b/resources/openpgp.js @@ -3044,13 +3044,25 @@ function openpgp_packet_keymaterial() { break; case 7: // - AES with 128-bit key [AES] case 8: // - AES with 192-bit key - case 9: // - AES with 256-bit key - cleartextMPIs = normal_cfb_decrypt(AESencrypt, - this.IVLength, keyExpansion(key), this.encryptedMPIData, this.IV); + case 9: // - AES with 256-bit key + var numBytes = 16; + //This is a weird way to achieve this. If's within a switch is probably not ideal. + if(this.symmetricEncryptionAlgorithm == 8){ + numBytes = 24; + key = this.s2k.produce_key(str_passphrase,numBytes); + } + if(this.symmetricEncryptionAlgorithm == 9){ + numBytes = 32; + key = this.s2k.produce_key(str_passphrase,numBytes); + } + cleartextMPIs = normal_cfb_decrypt(function(block,key){ + return AESencrypt(util.str2bin(block),key); + }, + this.IVLength, keyExpansion(key.substring(0,numBytes)), this.encryptedMPIData, this.IV); break; case 10: // - Twofish with 256-bit key [TWOFISH] util.print_error("openpgp.packet.keymaterial.js\n"+"Key material is encrypted with twofish: not implemented"); - return false;; + return false; case 5: // - Reserved case 6: // - Reserved default: @@ -11266,7 +11278,7 @@ function openpgp_type_s2k() { * @param passphrase [String] passphrase containing user input * @return [String] produced key with a length corresponding to hashAlgorithm hash length */ - function produce_key(passphrase) { + function produce_key(passphrase, numBytes) { if (this.type == 0) { return openpgp_crypto_hashData(this.hashAlgorithm,passphrase); } else if (this.type == 1) { @@ -11277,6 +11289,10 @@ function openpgp_type_s2k() { isp += this.saltValue+passphrase; if (isp.length > this.count) isp = isp.substr(0, this.count); + if(numBytes && (numBytes == 24 || numBytes == 32)){ //This if accounts for RFC 4880 3.7.1.1 -- If hash size is greater than block size, use leftmost bits. If blocksize larger than hash size, we need to rehash isp and prepend with 0. + var key = openpgp_crypto_hashData(this.hashAlgorithm,isp); + return key + openpgp_crypto_hashData(this.hashAlgorithm,String.fromCharCode(0)+isp); + } return openpgp_crypto_hashData(this.hashAlgorithm,isp); } else return null; } diff --git a/resources/openpgp.min.js b/resources/openpgp.min.js index dc2a2110..3947a362 100644 --- a/resources/openpgp.min.js +++ b/resources/openpgp.min.js @@ -19,17 +19,17 @@ this.version)return d=""+String.fromCharCode(this.version),d+=String.fromCharCod d=""+String.fromCharCode(this.version);d+=String.fromCharCode(255);d+=String.fromCharCode(this.signatureData.length>>24);d+=String.fromCharCode(this.signatureData.length>>16&255);d+=String.fromCharCode(this.signatureData.length>>8&255);d+=String.fromCharCode(this.signatureData.length&255);return openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,a.obj.publicKeyPacket.MPIs,this.signatureData+d);case 16:case 17:case 18:case 19:case 48:return d=""+String.fromCharCode(this.version), d+=String.fromCharCode(255),d+=String.fromCharCode(this.signatureData.length>>24),d+=String.fromCharCode(this.signatureData.length>>16&255),d+=String.fromCharCode(this.signatureData.length>>8&255),d+=String.fromCharCode(this.signatureData.length&255),openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,a.MPIs,b+this.signatureData+d);case 24:if(3==this.version)return!1;d=""+String.fromCharCode(this.version);d+=String.fromCharCode(255);d+=String.fromCharCode(this.signatureData.length>> 24);d+=String.fromCharCode(this.signatureData.length>>16&255);d+=String.fromCharCode(this.signatureData.length>>8&255);d+=String.fromCharCode(this.signatureData.length&255);return openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,a.MPIs,b+this.signatureData+d);case 25:case 31:case 32:case 40:return d=""+String.fromCharCode(this.version),d+=String.fromCharCode(255),d+=String.fromCharCode(this.signatureData.length>>24),d+=String.fromCharCode(this.signatureData.length>> -16&255),d+=String.fromCharCode(this.signatureData.length>>8&255),d+=String.fromCharCode(this.signatureData.length&255),openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,a.MPIs,b+this.signatureData+d);default:util.print_error("openpgp.packet.signature.js\nsignature verification for type"+this.signatureType+" not implemented")}};this.read_packet=function(a,c,d){this.data=a.substring(c,c+d);if(0>d)return util.print_debug("openpgp.packet.signature.js\nopenpgp_packet_signature read_packet length < 0 @:"+ -c),null;var e=c;this.packetLength=d;this.version=a[e++].charCodeAt();switch(this.version){case 3:5!=a[e++].charCodeAt()&&util.print_debug("openpgp.packet.signature.js\ninvalid One-octet length of following hashed material. MUST be 5. @:"+(e-1));this.signatureType=a[e++].charCodeAt();this.creationTime=new Date(1E3*(a[e++].charCodeAt()<<24|a[e++].charCodeAt()<<16|a[e++].charCodeAt()<<8|a[e++].charCodeAt()));this.signatureData=a.substring(c,e);this.keyId=a.substring(e,e+8);e+=8;this.publicKeyAlgorithm= -a[e++].charCodeAt();this.hashAlgorithm=a[e++].charCodeAt();this.signedHashValue=a[e++].charCodeAt()<<8|a[e++].charCodeAt();d=0;0this.publicKeyAlgorithm?d=1:17==this.publicKeyAlgorithm&&(d=2);this.MPIs=[];for(var f=0;fthis.publicKeyAlgorithm?d=1:17==this.publicKeyAlgorithm&&(d=2);this.MPIs=[];for(f=0;f>8&255),d+=String.fromCharCode(this.signatureData.length&255),openpgp_crypto_verifySignature(this.publicKeyAlgorithm,this.hashAlgorithm,this.MPIs,a.MPIs,b+this.signatureData+d);default:util.print_error("openpgp.packet.signature.js\nsignature verification for type"+this.signatureType+" not implemented")}};this.read_packet=function(b,a,d){this.data=b.substring(a,a+d);if(0>d)return util.print_debug("openpgp.packet.signature.js\nopenpgp_packet_signature read_packet length < 0 @:"+ +a),null;var e=a;this.packetLength=d;this.version=b[e++].charCodeAt();switch(this.version){case 3:5!=b[e++].charCodeAt()&&util.print_debug("openpgp.packet.signature.js\ninvalid One-octet length of following hashed material. MUST be 5. @:"+(e-1));this.signatureType=b[e++].charCodeAt();this.creationTime=new Date(1E3*(b[e++].charCodeAt()<<24|b[e++].charCodeAt()<<16|b[e++].charCodeAt()<<8|b[e++].charCodeAt()));this.signatureData=b.substring(a,e);this.keyId=b.substring(e,e+8);e+=8;this.publicKeyAlgorithm= +b[e++].charCodeAt();this.hashAlgorithm=b[e++].charCodeAt();this.signedHashValue=b[e++].charCodeAt()<<8|b[e++].charCodeAt();d=0;0this.publicKeyAlgorithm?d=1:17==this.publicKeyAlgorithm&&(d=2);this.MPIs=[];for(var f=0;fthis.publicKeyAlgorithm?d=1:17==this.publicKeyAlgorithm&&(d=2);this.MPIs=[];for(f=0;fthis.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(a, d,c-2-(d-b)),d+=this.secMPIs[0].packetLength,this.secMPIs[1]=new openpgp_type_mpi,this.secMPIs[1].read(a,d,c-2-(d-b)),d+=this.secMPIs[1].packetLength,this.secMPIs[2]=new openpgp_type_mpi,this.secMPIs[2].read(a,d,c-2-(d-b)),d+=this.secMPIs[2].packetLength,this.secMPIs[3]=new openpgp_type_mpi,this.secMPIs[3].read(a,d,c-2-(d-b)),d+=this.secMPIs[3].packetLength;else if(16==this.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(a,d,c-2-(d-b)),d+=this.secMPIs[0].packetLength; -else if(17==this.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(a,d,c-2-(d-b)),d+=this.secMPIs[0].packetLength;this.checksum=[];this.checksum[0]=a[d++].charCodeAt();this.checksum[1]=a[d++].charCodeAt()}else this.encryptedMPIData=a.substring(d,c);return this};this.decryptSecretMPIs=function(a){if(this.hasUnencryptedSecretKeyData)return this.secMPIs;var b=this.s2k.produce_key(a),a="";switch(this.symmetricEncryptionAlgorithm){case 1:return util.print_error("openpgp.packet.keymaterial.js\nsymmetric encryption algorithim: IDEA is not implemented"), -!1;case 2:a=normal_cfb_decrypt(function(a,b){return des(b,a,1,null,0)},this.IVLength,b,this.encryptedMPIData,this.IV);break;case 3:a=normal_cfb_decrypt(function(a,b){var c=new openpgp_symenc_cast5;c.setKey(b);return c.encrypt(util.str2bin(a))},this.IVLength,util.str2bin(b.substring(0,16)),this.encryptedMPIData,this.IV);break;case 4:a=normal_cfb_decrypt(function(a,b){return(new Blowfish(b)).encrypt(a)},this.IVLength,b,this.encryptedMPIData,this.IV);break;case 7:case 8:case 9:a=normal_cfb_decrypt(AESencrypt, -this.IVLength,keyExpansion(b),this.encryptedMPIData,this.IV);break;case 10:return util.print_error("openpgp.packet.keymaterial.js\nKey material is encrypted with twofish: not implemented"),!1;default:return util.print_error("openpgp.packet.keymaterial.js\nunknown encryption algorithm for secret key :"+this.symmetricEncryptionAlgorithm),!1}if(null==a)return util.print_error("openpgp.packet.keymaterial.js\ncleartextMPIs was null"),!1;b=a.length;if(254==this.s2kUsageConventions&&str_sha1(a.substring(0, -a.length-20))==a.substring(a.length-20))b-=20;else if(254!=this.s2kUsageConventions&&util.calc_checksum(a.substring(0,a.length-2))==(a.charCodeAt(a.length-2)<<8|a.charCodeAt(a.length-1)))b-=2;else return!1;if(0this.publicKey.publicKeyAlgorithm){var c=0;this.secMPIs=[];this.secMPIs[0]=new openpgp_type_mpi;this.secMPIs[0].read(a,0,b);c+=this.secMPIs[0].packetLength;this.secMPIs[1]=new openpgp_type_mpi;this.secMPIs[1].read(a,c,b-c);c+=this.secMPIs[1].packetLength; -this.secMPIs[2]=new openpgp_type_mpi;this.secMPIs[2].read(a,c,b-c);c+=this.secMPIs[2].packetLength;this.secMPIs[3]=new openpgp_type_mpi;this.secMPIs[3].read(a,c,b-c);c+=this.secMPIs[3].packetLength}else if(16==this.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(a,0,a);else if(17==this.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(a,0,b);return!0};this.read_nodes=function(a,b,c,d){this.parentNode= -a;if(14==this.tagType){for(var a=c,e=null;b.length!=a;)if(d=b.length-a,e=openpgp_packet.read_packet(b,a,d),null==e){util.print_error("openpgp.packet.keymaterial.js\n[user_keymat_pub]parsing ends here @:"+a+" l:"+d);break}else switch(e.tagType){case 2:if(24==e.signatureType){this.subKeySignature=e;a+=e.packetLength+e.headerLength;break}else if(40==e.signatureType){this.subKeyRevocationSignature=e;a+=e.packetLength+e.headerLength;break}else util.print_error("openpgp.packet.keymaterial.js\nunknown signature:"+ -e.toString());default:return this.data=b,this.position=c-this.parentNode.packetLength,this.len=a-c}this.data=b;this.position=c-this.parentNode.packetLength;return this.len=a-c}if(7==this.tagType){for(a=c;b.length!=a;)if(e=openpgp_packet.read_packet(b,a,d-(a-c)),null==e){util.print_error("openpgp.packet.keymaterial.js\n[user_keymat_priv] parsing ends here @:"+a);break}else switch(e.tagType){case 2:24==e.signatureType?this.subKeySignature=e:40==e.signatureType&&(this.subKeyRevocationSignature[this.subKeyRevocationSignature]= -e);a+=e.packetLength+e.headerLength;break;default:return this.data=b,this.position=c-this.parentNode.packetLength,this.len=a-c}this.data=b;this.position=c-this.parentNode.packetLength;return this.len=a-c}util.print_error("openpgp.packet.keymaterial.js\nunknown parent node for a key material packet "+a.tagType)};this.verifyKey=function(){if(14==this.tagType){if(null==this.subKeySignature)return 0;if(4==this.subKeySignature.version&&null!=this.subKeySignature.keyNeverExpires&&!this.subKeySignature.keyNeverExpires&& -new Date(1E3*this.subKeySignature.keyExpirationTime+this.creationTime.getTime())this.publicKeyAlgorithm){var a=this.MPIs[0].substring(this.MPIs[0].mpiByteLength-8);util.print_debug("openpgp.msg.publickey read_nodes:\nV3 key ID: "+a);return a}};this.getFingerprint=function(){if(4==this.version)return tohash=String.fromCharCode(153)+ -String.fromCharCode(this.packetdata.length>>8&255)+String.fromCharCode(this.packetdata.length&255)+this.packetdata,util.print_debug("openpgp.msg.publickey creating subkey fingerprint by hashing:"+util.hexstrdump(tohash)+"\npublickeyalgorithm: "+this.publicKeyAlgorithm),str_sha1(tohash,tohash.length);if(3==this.version&&0this.publicKeyAlgorithm)return MD5(this.MPIs[0].MPI)};this.write_private_key=function(a,b,c,d,e,f){this.symmetricEncryptionAlgorithm=e;e=String.fromCharCode(4); -e+=f;switch(a){case 1:e+=String.fromCharCode(a);e+=b.n.toMPI();e+=b.ee.toMPI();if(c){e+=String.fromCharCode(254);e+=String.fromCharCode(this.symmetricEncryptionAlgorithm);e+=String.fromCharCode(3);e+=String.fromCharCode(d);a=b.d.toMPI()+b.p.toMPI()+b.q.toMPI()+b.u.toMPI();b=str_sha1(a);util.print_debug_hexstr_dump("write_private_key sha1: ",b);f=openpgp_crypto_getRandomBytes(8);util.print_debug_hexstr_dump("write_private_key Salt: ",f);var e=e+f,g=openpgp_crypto_getSecureRandomOctet(),e=e+String.fromCharCode(g); -util.print_debug("write_private_key c: "+g);c=(new openpgp_type_s2k).write(3,d,c,f,g);switch(this.symmetricEncryptionAlgorithm){case 3:this.IVLength=8;this.IV=openpgp_crypto_getRandomBytes(this.IVLength);ciphertextMPIs=normal_cfb_encrypt(function(a,b){var c=new openpgp_symenc_cast5;c.setKey(b);return c.encrypt(util.str2bin(a))},this.IVLength,util.str2bin(c.substring(0,16)),a+b,this.IV);e+=this.IV+ciphertextMPIs;break;case 7:case 8:case 9:this.IVLength=16,this.IV=openpgp_crypto_getRandomBytes(this.IVLength), -ciphertextMPIs=normal_cfb_encrypt(AESencrypt,this.IVLength,c,a+b,this.IV),e+=this.IV+ciphertextMPIs}}else e+=String.fromCharCode(0),e+=b.d.toMPI()+b.p.toMPI()+b.q.toMPI()+b.u.toMPI(),c=util.calc_checksum(b.d.toMPI()+b.p.toMPI()+b.q.toMPI()+b.u.toMPI()),e+=String.fromCharCode(c/256)+String.fromCharCode(c%256),util.print_debug_hexstr_dump("write_private_key basic checksum: "+c);break;default:e="",util.print_error("openpgp.packet.keymaterial.js\nerror writing private key, unknown type :"+a)}c=openpgp_packet.write_packet_header(5, -e.length);return{string:c+e,header:c,body:e}};this.write_public_key=function(a,b,c){var d=String.fromCharCode(4),d=d+c;switch(a){case 1:d+=String.fromCharCode(1);d+=b.n.toMPI();d+=b.ee.toMPI();break;default:util.print_error("openpgp.packet.keymaterial.js\nerror writing private key, unknown type :"+a)}a=openpgp_packet.write_packet_header(6,d.length);return{string:a+d,header:a,body:d}}}function MD5(a){a=md5(a);return util.hex2bin(a)} +else if(17==this.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(a,d,c-2-(d-b)),d+=this.secMPIs[0].packetLength;this.checksum=[];this.checksum[0]=a[d++].charCodeAt();this.checksum[1]=a[d++].charCodeAt()}else this.encryptedMPIData=a.substring(d,c);return this};this.decryptSecretMPIs=function(a){if(this.hasUnencryptedSecretKeyData)return this.secMPIs;var b=this.s2k.produce_key(a),c="";switch(this.symmetricEncryptionAlgorithm){case 1:return util.print_error("openpgp.packet.keymaterial.js\nsymmetric encryption algorithim: IDEA is not implemented"), +!1;case 2:c=normal_cfb_decrypt(function(a,b){return des(b,a,1,null,0)},this.IVLength,b,this.encryptedMPIData,this.IV);break;case 3:c=normal_cfb_decrypt(function(a,b){var c=new openpgp_symenc_cast5;c.setKey(b);return c.encrypt(util.str2bin(a))},this.IVLength,util.str2bin(b.substring(0,16)),this.encryptedMPIData,this.IV);break;case 4:c=normal_cfb_decrypt(function(a,b){return(new Blowfish(b)).encrypt(a)},this.IVLength,b,this.encryptedMPIData,this.IV);break;case 7:case 8:case 9:c=16;8==this.symmetricEncryptionAlgorithm&& +(c=24,b=this.s2k.produce_key(a,c));9==this.symmetricEncryptionAlgorithm&&(c=32,b=this.s2k.produce_key(a,c));c=normal_cfb_decrypt(function(a,b){return AESencrypt(util.str2bin(a),b)},this.IVLength,keyExpansion(b.substring(0,c)),this.encryptedMPIData,this.IV);break;case 10:return util.print_error("openpgp.packet.keymaterial.js\nKey material is encrypted with twofish: not implemented"),!1;default:return util.print_error("openpgp.packet.keymaterial.js\nunknown encryption algorithm for secret key :"+this.symmetricEncryptionAlgorithm), +!1}if(null==c)return util.print_error("openpgp.packet.keymaterial.js\ncleartextMPIs was null"),!1;a=c.length;if(254==this.s2kUsageConventions&&str_sha1(c.substring(0,c.length-20))==c.substring(c.length-20))a-=20;else if(254!=this.s2kUsageConventions&&util.calc_checksum(c.substring(0,c.length-2))==(c.charCodeAt(c.length-2)<<8|c.charCodeAt(c.length-1)))a-=2;else return!1;if(0this.publicKey.publicKeyAlgorithm)b=0,this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi, +this.secMPIs[0].read(c,0,a),b+=this.secMPIs[0].packetLength,this.secMPIs[1]=new openpgp_type_mpi,this.secMPIs[1].read(c,b,a-b),b+=this.secMPIs[1].packetLength,this.secMPIs[2]=new openpgp_type_mpi,this.secMPIs[2].read(c,b,a-b),b+=this.secMPIs[2].packetLength,this.secMPIs[3]=new openpgp_type_mpi,this.secMPIs[3].read(c,b,a-b),b+=this.secMPIs[3].packetLength;else if(16==this.publicKey.publicKeyAlgorithm)this.secMPIs=[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(c,0,c);else if(17==this.publicKey.publicKeyAlgorithm)this.secMPIs= +[],this.secMPIs[0]=new openpgp_type_mpi,this.secMPIs[0].read(c,0,a);return!0};this.read_nodes=function(a,b,c,d){this.parentNode=a;if(14==this.tagType){for(var a=c,e=null;b.length!=a;)if(d=b.length-a,e=openpgp_packet.read_packet(b,a,d),null==e){util.print_error("openpgp.packet.keymaterial.js\n[user_keymat_pub]parsing ends here @:"+a+" l:"+d);break}else switch(e.tagType){case 2:if(24==e.signatureType){this.subKeySignature=e;a+=e.packetLength+e.headerLength;break}else if(40==e.signatureType){this.subKeyRevocationSignature= +e;a+=e.packetLength+e.headerLength;break}else util.print_error("openpgp.packet.keymaterial.js\nunknown signature:"+e.toString());default:return this.data=b,this.position=c-this.parentNode.packetLength,this.len=a-c}this.data=b;this.position=c-this.parentNode.packetLength;return this.len=a-c}if(7==this.tagType){for(a=c;b.length!=a;)if(e=openpgp_packet.read_packet(b,a,d-(a-c)),null==e){util.print_error("openpgp.packet.keymaterial.js\n[user_keymat_priv] parsing ends here @:"+a);break}else switch(e.tagType){case 2:24== +e.signatureType?this.subKeySignature=e:40==e.signatureType&&(this.subKeyRevocationSignature[this.subKeyRevocationSignature]=e);a+=e.packetLength+e.headerLength;break;default:return this.data=b,this.position=c-this.parentNode.packetLength,this.len=a-c}this.data=b;this.position=c-this.parentNode.packetLength;return this.len=a-c}util.print_error("openpgp.packet.keymaterial.js\nunknown parent node for a key material packet "+a.tagType)};this.verifyKey=function(){if(14==this.tagType){if(null==this.subKeySignature)return 0; +if(4==this.subKeySignature.version&&null!=this.subKeySignature.keyNeverExpires&&!this.subKeySignature.keyNeverExpires&&new Date(1E3*this.subKeySignature.keyExpirationTime+this.creationTime.getTime())this.publicKeyAlgorithm){var a=this.MPIs[0].substring(this.MPIs[0].mpiByteLength-8);util.print_debug("openpgp.msg.publickey read_nodes:\nV3 key ID: "+ +a);return a}};this.getFingerprint=function(){if(4==this.version)return tohash=String.fromCharCode(153)+String.fromCharCode(this.packetdata.length>>8&255)+String.fromCharCode(this.packetdata.length&255)+this.packetdata,util.print_debug("openpgp.msg.publickey creating subkey fingerprint by hashing:"+util.hexstrdump(tohash)+"\npublickeyalgorithm: "+this.publicKeyAlgorithm),str_sha1(tohash,tohash.length);if(3==this.version&&0this.publicKeyAlgorithm)return MD5(this.MPIs[0].MPI)}; +this.write_private_key=function(a,b,c,d,e,f){this.symmetricEncryptionAlgorithm=e;e=String.fromCharCode(4);e+=f;switch(a){case 1:e+=String.fromCharCode(a);e+=b.n.toMPI();e+=b.ee.toMPI();if(c){e+=String.fromCharCode(254);e+=String.fromCharCode(this.symmetricEncryptionAlgorithm);e+=String.fromCharCode(3);e+=String.fromCharCode(d);a=b.d.toMPI()+b.p.toMPI()+b.q.toMPI()+b.u.toMPI();b=str_sha1(a);util.print_debug_hexstr_dump("write_private_key sha1: ",b);f=openpgp_crypto_getRandomBytes(8);util.print_debug_hexstr_dump("write_private_key Salt: ", +f);var e=e+f,g=openpgp_crypto_getSecureRandomOctet(),e=e+String.fromCharCode(g);util.print_debug("write_private_key c: "+g);c=(new openpgp_type_s2k).write(3,d,c,f,g);switch(this.symmetricEncryptionAlgorithm){case 3:this.IVLength=8;this.IV=openpgp_crypto_getRandomBytes(this.IVLength);ciphertextMPIs=normal_cfb_encrypt(function(a,b){var c=new openpgp_symenc_cast5;c.setKey(b);return c.encrypt(util.str2bin(a))},this.IVLength,util.str2bin(c.substring(0,16)),a+b,this.IV);e+=this.IV+ciphertextMPIs;break; +case 7:case 8:case 9:this.IVLength=16,this.IV=openpgp_crypto_getRandomBytes(this.IVLength),ciphertextMPIs=normal_cfb_encrypt(AESencrypt,this.IVLength,c,a+b,this.IV),e+=this.IV+ciphertextMPIs}}else e+=String.fromCharCode(0),e+=b.d.toMPI()+b.p.toMPI()+b.q.toMPI()+b.u.toMPI(),c=util.calc_checksum(b.d.toMPI()+b.p.toMPI()+b.q.toMPI()+b.u.toMPI()),e+=String.fromCharCode(c/256)+String.fromCharCode(c%256),util.print_debug_hexstr_dump("write_private_key basic checksum: "+c);break;default:e="",util.print_error("openpgp.packet.keymaterial.js\nerror writing private key, unknown type :"+ +a)}c=openpgp_packet.write_packet_header(5,e.length);return{string:c+e,header:c,body:e}};this.write_public_key=function(a,b,c){var d=String.fromCharCode(4),d=d+c;switch(a){case 1:d+=String.fromCharCode(1);d+=b.n.toMPI();d+=b.ee.toMPI();break;default:util.print_error("openpgp.packet.keymaterial.js\nerror writing private key, unknown type :"+a)}a=openpgp_packet.write_packet_header(6,d.length);return{string:a+d,header:a,body:d}}}function MD5(a){a=md5(a);return util.hex2bin(a)} function md5cycle(a,b){var c=a[0],d=a[1],e=a[2],f=a[3],c=ff(c,d,e,f,b[0],7,-680876936),f=ff(f,c,d,e,b[1],12,-389564586),e=ff(e,f,c,d,b[2],17,606105819),d=ff(d,e,f,c,b[3],22,-1044525330),c=ff(c,d,e,f,b[4],7,-176418897),f=ff(f,c,d,e,b[5],12,1200080426),e=ff(e,f,c,d,b[6],17,-1473231341),d=ff(d,e,f,c,b[7],22,-45705983),c=ff(c,d,e,f,b[8],7,1770035416),f=ff(f,c,d,e,b[9],12,-1958414417),e=ff(e,f,c,d,b[10],17,-42063),d=ff(d,e,f,c,b[11],22,-1990404162),c=ff(c,d,e,f,b[12],7,1804603682),f=ff(f,c,d,e,b[13],12, -40341101),e=ff(e,f,c,d,b[14],17,-1502002290),d=ff(d,e,f,c,b[15],22,1236535329),c=gg(c,d,e,f,b[1],5,-165796510),f=gg(f,c,d,e,b[6],9,-1069501632),e=gg(e,f,c,d,b[11],14,643717713),d=gg(d,e,f,c,b[0],20,-373897302),c=gg(c,d,e,f,b[5],5,-701558691),f=gg(f,c,d,e,b[10],9,38016083),e=gg(e,f,c,d,b[15],14,-660478335),d=gg(d,e,f,c,b[4],20,-405537848),c=gg(c,d,e,f,b[9],5,568446438),f=gg(f,c,d,e,b[14],9,-1019803690),e=gg(e,f,c,d,b[3],14,-187363961),d=gg(d,e,f,c,b[8],20,1163531501),c=gg(c,d,e,f,b[13],5,-1444681467), f=gg(f,c,d,e,b[2],9,-51403784),e=gg(e,f,c,d,b[7],14,1735328473),d=gg(d,e,f,c,b[12],20,-1926607734),c=hh(c,d,e,f,b[5],4,-378558),f=hh(f,c,d,e,b[8],11,-2022574463),e=hh(e,f,c,d,b[11],16,1839030562),d=hh(d,e,f,c,b[14],23,-35309556),c=hh(c,d,e,f,b[1],4,-1530992060),f=hh(f,c,d,e,b[4],11,1272893353),e=hh(e,f,c,d,b[7],16,-155497632),d=hh(d,e,f,c,b[10],23,-1094730640),c=hh(c,d,e,f,b[13],4,681279174),f=hh(f,c,d,e,b[0],11,-358537222),e=hh(e,f,c,d,b[3],16,-722521979),d=hh(d,e,f,c,b[6],23,76029189),c=hh(c,d, @@ -429,8 +429,8 @@ function openpgp_type_mpi(){this.data=this.mpiByteLength=this.mpiBitLength=this. 16)};this.toString=function(){var a=" MPI("+this.mpiBitLength+"b/"+this.mpiByteLength+"B) : 0x",a=a+util.hexstrdump(this.MPI);return a+"\n"};this.create=function(a){this.MPI=a;var b=8*(a.length-1),c;a:for(var d=a.charCodeAt(0),e=0;9>e;e++)if(0==d>>e){c=e;break a}this.mpiBitLength=b+c;this.mpiByteLength=a.length;return this};this.toBin=function(){var a=String.fromCharCode(this.mpiBitLength>>8&255),a=a+String.fromCharCode(this.mpiBitLength&255);return a+=this.MPI};this.getByteLength=function(){return this.mpiByteLength}} function openpgp_type_keyid(){this.read_packet=function(a,b){this.bytes=a.substring(b,b+8);return this};this.toString=function(){return util.hexstrdump(this.bytes)}} function openpgp_type_s2k(){this.read=function(a,b){var c=b;this.type=a[c++].charCodeAt();switch(this.type){case 0:this.hashAlgorithm=a[c++].charCodeAt();this.s2kLength=1;break;case 1:this.hashAlgorithm=a[c++].charCodeAt();this.saltValue=a.substring(c,c+8);this.s2kLength=9;break;case 3:this.hashAlgorithm=a[c++].charCodeAt();this.saltValue=a.substring(c,c+8);c+=8;this.EXPBIAS=6;c=a[c++].charCodeAt();this.count=16+(c&15)<<(c>>4)+this.EXPBIAS;this.s2kLength=10;break;default:util.print_error("unknown s2k type! "+ -this.type)}return this};this.write=function(a,b,c,d,e){this.type=a;if(3==this.type)this.saltValue=d,this.hashAlgorithm=b,this.count=16+(e&15)<<(e>>4)+6,this.s2kLength=10;return this.produce_key(c)};this.produce_key=function(a){if(0==this.type)return openpgp_crypto_hashData(this.hashAlgorithm,a);if(1==this.type)return openpgp_crypto_hashData(this.hashAlgorithm,this.saltValue+a);if(3==this.type){for(var b=this.saltValue+a;b.lengththis.count&&(b=b.substr(0,this.count)); -return openpgp_crypto_hashData(this.hashAlgorithm,b)}return null}} +this.type)}return this};this.write=function(a,b,c,d,e){this.type=a;if(3==this.type)this.saltValue=d,this.hashAlgorithm=b,this.count=16+(e&15)<<(e>>4)+6,this.s2kLength=10;return this.produce_key(c)};this.produce_key=function(a,b){if(0==this.type)return openpgp_crypto_hashData(this.hashAlgorithm,a);if(1==this.type)return openpgp_crypto_hashData(this.hashAlgorithm,this.saltValue+a);if(3==this.type){for(var c=this.saltValue+a;c.lengththis.count&&(c=c.substr(0, +this.count));return b&&(24==b||32==b)?openpgp_crypto_hashData(this.hashAlgorithm,c)+openpgp_crypto_hashData(this.hashAlgorithm,String.fromCharCode(0)+c):openpgp_crypto_hashData(this.hashAlgorithm,c)}return null}} function openpgp_keyring(){this.init=function(){var a=JSON.parse(window.localStorage.getItem("privatekeys")),b=JSON.parse(window.localStorage.getItem("publickeys"));if(null==a||0==a.length)a=[];if(null==b||0==b.length)b=[];this.publicKeys=[];this.privateKeys=[];for(var c=0,d=0;d")[0]: a.trim(),a=0;a")[0]:a.trim(),a=0;a this.count) isp = isp.substr(0, this.count); + if(numBytes && (numBytes == 24 || numBytes == 32)){ //This if accounts for RFC 4880 3.7.1.1 -- If hash size is greater than block size, use leftmost bits. If blocksize larger than hash size, we need to rehash isp and prepend with 0. + var key = openpgp_crypto_hashData(this.hashAlgorithm,isp); + return key + openpgp_crypto_hashData(this.hashAlgorithm,String.fromCharCode(0)+isp); + } return openpgp_crypto_hashData(this.hashAlgorithm,isp); } else return null; }