# Source: crypto/pkcs1.js

    // GPG4Browsers - An OpenPGP implementation in javascript
    // Copyright (C) 2011 Recurity Labs GmbH
    //
    // This library is free software; you can redistribute it and/or
    // modify it under the terms of the GNU Lesser General Public
    // License as published by the Free Software Foundation; either
    // version 2.1 of the License, or (at your option) any later version.
    //
    // This library is distributed in the hope that it will be useful,
    // but WITHOUT ANY WARRANTY; without even the implied warranty of
    // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    // Lesser General Public License for more details.
    //
    // You should have received a copy of the GNU Lesser General Public
    // License along with this library; if not, write to the Free Software
    // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

    /** @module crypto/pkcs1 */

    /**
     * ASN1 object identifiers for hashes (See RFC4880 5.2.2)
     */
    hash_headers = new Array();
    hash_headers[1] = [0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04,
        0x10
    ];
    hash_headers[3] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14];
    hash_headers[2] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14];
    hash_headers[8] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
        0x04, 0x20
    ];
    hash_headers[9] = [0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00,
        0x04, 0x30
    ];
    hash_headers[10] = [0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
        0x00, 0x04, 0x40
    ];
    hash_headers[11] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05,
        0x00, 0x04, 0x1C
    ];

    var crypto = require('./crypto.js'),
      random = require('./random.js'),
      util = require('../util'),
      BigInteger = require('./public_key/jsbn.js'),
      hash = require('./hash');

    module.exports = {
      eme: {
        /**
         * create a EME-PKCS1-v1_5 padding (See RFC4880 13.1.1)
         * @param {String} message message to be padded
         * @param {Integer} length Length to the resulting message
         * @return {String} EME-PKCS1 padded message
         */
        encode: function(message, length) {
          if (message.length > length - 11)
            return -1;
          var result = "";
          result += String.fromCharCode(0);
          result += String.fromCharCode(2);
          for (var i = 0; i < length - message.length - 3; i++) {
            result += String.fromCharCode(random.getPseudoRandom(1, 255));
          }
          result += String.fromCharCode(0);
          result += message;
          return result;
        },

        /**
         * decodes a EME-PKCS1-v1_5 padding (See RFC4880 13.1.2)
         * @param {String} message EME-PKCS1 padded message
         * @return {String} decoded message
         */
        decode: function(message, len) {
          if (message.length < len)
            message = String.fromCharCode(0) + message;
          if (message.length < 12 || message.charCodeAt(0) != 0 || message.charCodeAt(1) != 2)
            return -1;
          var i = 2;
          while (message.charCodeAt(i) != 0 && message.length > i)
            i++;
          return message.substring(i + 1, message.length);
        },
      },

      emsa: {

        /**
         * create a EMSA-PKCS1-v1_5 padding (See RFC4880 13.1.3)
         * @param {Integer} algo Hash algorithm type used
         * @param {String} data Data to be hashed
         * @param {Integer} keylength Key size of the public mpi in bytes
         * @returns {String} Hashcode with pkcs1padding as string
         */
        encode: function(algo, data, keylength) {
          var data2 = "";
          data2 += String.fromCharCode(0x00);
          data2 += String.fromCharCode(0x01);
          for (var i = 0; i < (keylength - hash_headers[algo].length - 3 -
            hash.getHashByteLength(algo)); i++)

            data2 += String.fromCharCode(0xff);

          data2 += String.fromCharCode(0x00);

          for (var i = 0; i < hash_headers[algo].length; i++)
            data2 += String.fromCharCode(hash_headers[algo][i]);

          data2 += hash.digest(algo, data);
          return new BigInteger(util.hexstrdump(data2), 16);
        },

        /**
         * extract the hash out of an EMSA-PKCS1-v1.5 padding (See RFC4880 13.1.3)
         * @param {String} data Hash in pkcs1 encoding
         * @returns {String} The hash as string
         */
        decode: function(algo, data) {
          var i = 0;
          if (data.charCodeAt(0) == 0) i++;
          else if (data.charCodeAt(0) != 1) return -1;
          else i++;

          while (data.charCodeAt(i) == 0xFF) i++;
          if (data.charCodeAt(i++) != 0) return -1;
          var j = 0;
          for (j = 0; j < hash_headers[algo].length && j + i < data.length; j++) {
            if (data.charCodeAt(j + i) != hash_headers[algo][j]) return -1;
          }
          i += j;
          if (data.substring(i).length < hash.getHashByteLength(algo)) return -1;
          return data.substring(i);
        }
      }
    }