rsawrapr.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:26k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * PKCS#1 encoding and decoding functions.
  3.  * This file is believed to contain no code licensed from other parties.
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public
  6.  * License Version 1.1 (the "License"); you may not use this file
  7.  * except in compliance with the License. You may obtain a copy of
  8.  * the License at http://www.mozilla.org/MPL/
  9.  * 
  10.  * Software distributed under the License is distributed on an "AS
  11.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  12.  * implied. See the License for the specific language governing
  13.  * rights and limitations under the License.
  14.  * 
  15.  * The Original Code is the Netscape security libraries.
  16.  * 
  17.  * The Initial Developer of the Original Code is Netscape
  18.  * Communications Corporation.  Portions created by Netscape are 
  19.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  20.  * Rights Reserved.
  21.  * 
  22.  * Contributor(s):
  23.  * 
  24.  * Alternatively, the contents of this file may be used under the
  25.  * terms of the GNU General Public License Version 2 or later (the
  26.  * "GPL"), in which case the provisions of the GPL are applicable 
  27.  * instead of those above.  If you wish to allow use of your 
  28.  * version of this file only under the terms of the GPL and not to
  29.  * allow others to use your version of this file under the MPL,
  30.  * indicate your decision by deleting the provisions above and
  31.  * replace them with the notice and other provisions required by
  32.  * the GPL.  If you do not delete the provisions above, a recipient
  33.  * may use your version of this file under either the MPL or the
  34.  * GPL.
  35.  *
  36.  * $Id: rsawrapr.c,v 1.1 2000/03/31 19:29:42 relyea%netscape.com Exp $
  37.  */
  38. #include "blapi.h"
  39. #include "softoken.h"
  40. #include "sechash.h"
  41. #include "keylow.h"
  42. #include "secerr.h"
  43. #define RSA_BLOCK_MIN_PAD_LEN 8
  44. #define RSA_BLOCK_FIRST_OCTET 0x00
  45. #define RSA_BLOCK_PRIVATE0_PAD_OCTET 0x00
  46. #define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff
  47. #define RSA_BLOCK_AFTER_PAD_OCTET 0x00
  48. #define OAEP_SALT_LEN 8
  49. #define OAEP_PAD_LEN 8
  50. #define OAEP_PAD_OCTET 0x00
  51. #define FLAT_BUFSIZE 512 /* bytes to hold flattened SHA1Context. */
  52. static SHA1Context *
  53. SHA1_CloneContext(SHA1Context *original)
  54. {
  55.     SHA1Context *  clone = NULL;
  56.     unsigned char *pBuf;
  57.     int            sha1ContextSize = SHA1_FlattenSize(original);
  58.     SECStatus      frv;
  59.     unsigned char  buf[FLAT_BUFSIZE];
  60.     PORT_Assert(sizeof buf >= sha1ContextSize);
  61.     if (sizeof buf >= sha1ContextSize) {
  62.      pBuf = buf;
  63.     } else {
  64.         pBuf = PORT_Alloc(sha1ContextSize);
  65. if (!pBuf)
  66.     goto done;
  67.     }
  68.     frv = SHA1_Flatten(original, pBuf);
  69.     if (frv == SECSuccess) {
  70. clone = SHA1_Resurrect(pBuf, NULL);
  71. memset(pBuf, 0, sha1ContextSize);
  72.     }
  73. done:
  74.     if (pBuf != buf)
  75.      PORT_Free(pBuf);
  76.     return clone;
  77. }
  78. /*
  79.  * Modify data by XORing it with a special hash of salt.
  80.  */
  81. static SECStatus
  82. oaep_xor_with_h1(unsigned char *data, unsigned int datalen,
  83.  unsigned char *salt, unsigned int saltlen)
  84. {
  85.     SHA1Context *sha1cx;
  86.     unsigned char *dp, *dataend;
  87.     unsigned char end_octet;
  88.     sha1cx = SHA1_NewContext();
  89.     if (sha1cx == NULL) {
  90. return SECFailure;
  91.     }
  92.     /*
  93.      * Get a hash of salt started; we will use it several times,
  94.      * adding in a different end octet (x00, x01, x02, ...).
  95.      */
  96.     SHA1_Begin (sha1cx);
  97.     SHA1_Update (sha1cx, salt, saltlen);
  98.     end_octet = 0;
  99.     dp = data;
  100.     dataend = data + datalen;
  101.     while (dp < dataend) {
  102. SHA1Context *sha1cx_h1;
  103. unsigned int sha1len, sha1off;
  104. unsigned char sha1[SHA1_LENGTH];
  105. /*
  106.  * Create hash of (salt || end_octet)
  107.  */
  108. sha1cx_h1 = SHA1_CloneContext (sha1cx);
  109. SHA1_Update (sha1cx_h1, &end_octet, 1);
  110. SHA1_End (sha1cx_h1, sha1, &sha1len, sizeof(sha1));
  111. SHA1_DestroyContext (sha1cx_h1, PR_TRUE);
  112. PORT_Assert (sha1len == SHA1_LENGTH);
  113. /*
  114.  * XOR that hash with the data.
  115.  * When we have fewer than SHA1_LENGTH octets of data
  116.  * left to xor, use just the low-order ones of the hash.
  117.  */
  118. sha1off = 0;
  119. if ((dataend - dp) < SHA1_LENGTH)
  120.     sha1off = SHA1_LENGTH - (dataend - dp);
  121. while (sha1off < SHA1_LENGTH)
  122.     *dp++ ^= sha1[sha1off++];
  123. /*
  124.  * Bump for next hash chunk.
  125.  */
  126. end_octet++;
  127.     }
  128.     return SECSuccess;
  129. }
  130. /*
  131.  * Modify salt by XORing it with a special hash of data.
  132.  */
  133. static SECStatus
  134. oaep_xor_with_h2(unsigned char *salt, unsigned int saltlen,
  135.  unsigned char *data, unsigned int datalen)
  136. {
  137.     unsigned char sha1[SHA1_LENGTH];
  138.     unsigned char *psalt, *psha1, *saltend;
  139.     SECStatus rv;
  140.     /*
  141.      * Create a hash of data.
  142.      */
  143.     rv = SHA1_HashBuf (sha1, data, datalen);
  144.     if (rv != SECSuccess) {
  145. return rv;
  146.     }
  147.     /*
  148.      * XOR the low-order octets of that hash with salt.
  149.      */
  150.     PORT_Assert (saltlen <= SHA1_LENGTH);
  151.     saltend = salt + saltlen;
  152.     psalt = salt;
  153.     psha1 = sha1 + SHA1_LENGTH - saltlen;
  154.     while (psalt < saltend) {
  155. *psalt++ ^= *psha1++;
  156.     }
  157.     return SECSuccess;
  158. }
  159. /*
  160.  * Format one block of data for public/private key encryption using
  161.  * the rules defined in PKCS #1.
  162.  */
  163. unsigned char *
  164. RSA_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
  165.    SECItem *data)
  166. {
  167.     unsigned char *block;
  168.     unsigned char *bp;
  169.     int padLen;
  170.     int i;
  171.     block = (unsigned char *) PORT_Alloc(modulusLen);
  172.     if (block == NULL)
  173. return NULL;
  174.     bp = block;
  175.     /*
  176.      * All RSA blocks start with two octets:
  177.      * 0x00 || BlockType
  178.      */
  179.     *bp++ = RSA_BLOCK_FIRST_OCTET;
  180.     *bp++ = (unsigned char) blockType;
  181.     switch (blockType) {
  182.       /*
  183.        * Blocks intended for private-key operation.
  184.        */
  185.       case RSA_BlockPrivate0: /* essentially unused */
  186.       case RSA_BlockPrivate:  /* preferred method */
  187. /*
  188.  * 0x00 || BT || Pad || 0x00 || ActualData
  189.  *   1      1   padLen    1      data->len
  190.  * Pad is either all 0x00 or all 0xff bytes, depending on blockType.
  191.  */
  192. padLen = modulusLen - data->len - 3;
  193. PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
  194. PORT_Memset (bp,
  195.    blockType == RSA_BlockPrivate0
  196. ? RSA_BLOCK_PRIVATE0_PAD_OCTET
  197. : RSA_BLOCK_PRIVATE_PAD_OCTET,
  198.    padLen);
  199. bp += padLen;
  200. *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
  201. PORT_Memcpy (bp, data->data, data->len);
  202. break;
  203.       /*
  204.        * Blocks intended for public-key operation.
  205.        */
  206.       case RSA_BlockPublic:
  207. /*
  208.  * 0x00 || BT || Pad || 0x00 || ActualData
  209.  *   1      1   padLen    1      data->len
  210.  * Pad is all non-zero random bytes.
  211.  */
  212. padLen = modulusLen - data->len - 3;
  213. PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
  214. for (i = 0; i < padLen; i++) {
  215.     /* Pad with non-zero random data. */
  216.     do {
  217. RNG_GenerateGlobalRandomBytes(bp + i, 1);
  218.     } while (bp[i] == RSA_BLOCK_AFTER_PAD_OCTET);
  219. }
  220. bp += padLen;
  221. *bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
  222. PORT_Memcpy (bp, data->data, data->len);
  223. break;
  224.       /*
  225.        * Blocks intended for public-key operation, using
  226.        * Optimal Asymmetric Encryption Padding (OAEP).
  227.        */
  228.       case RSA_BlockOAEP:
  229. /*
  230.  * 0x00 || BT || Modified2(Salt) || Modified1(PaddedData)
  231.  *   1      1     OAEP_SALT_LEN     OAEP_PAD_LEN + data->len [+ N]
  232.  *
  233.  * where:
  234.  *   PaddedData is "Pad1 || ActualData [|| Pad2]"
  235.  *   Salt is random data.
  236.  *   Pad1 is all zeros.
  237.  *   Pad2, if present, is random data.
  238.  *   (The "modified" fields are all the same length as the original
  239.  * unmodified values; they are just xor'd with other values.)
  240.  *
  241.  *   Modified1 is an XOR of PaddedData with a special octet
  242.  * string constructed of iterated hashing of Salt (see below).
  243.  *   Modified2 is an XOR of Salt with the low-order octets of
  244.  * the hash of Modified1 (see farther below ;-).
  245.  *
  246.  * Whew!
  247.  */
  248. /*
  249.  * Salt
  250.  */
  251. RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN);
  252. bp += OAEP_SALT_LEN;
  253. /*
  254.  * Pad1
  255.  */
  256. PORT_Memset (bp, OAEP_PAD_OCTET, OAEP_PAD_LEN);
  257. bp += OAEP_PAD_LEN;
  258. /*
  259.  * Data
  260.  */
  261. PORT_Memcpy (bp, data->data, data->len);
  262. bp += data->len;
  263. /*
  264.  * Pad2
  265.  */
  266. if (bp < (block + modulusLen))
  267.     RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen);
  268. /*
  269.  * Now we have the following:
  270.  * 0x00 || BT || Salt || PaddedData
  271.  * (From this point on, "Pad1 || Data [|| Pad2]" is treated
  272.  * as the one entity PaddedData.)
  273.  *
  274.  * We need to turn PaddedData into Modified1.
  275.  */
  276. if (oaep_xor_with_h1(block + 2 + OAEP_SALT_LEN,
  277.      modulusLen - 2 - OAEP_SALT_LEN,
  278.      block + 2, OAEP_SALT_LEN) != SECSuccess) {
  279.     PORT_Free (block);
  280.     return NULL;
  281. }
  282. /*
  283.  * Now we have:
  284.  * 0x00 || BT || Salt || Modified1(PaddedData)
  285.  *
  286.  * The remaining task is to turn Salt into Modified2.
  287.  */
  288. if (oaep_xor_with_h2(block + 2, OAEP_SALT_LEN,
  289.      block + 2 + OAEP_SALT_LEN,
  290.      modulusLen - 2 - OAEP_SALT_LEN) != SECSuccess) {
  291.     PORT_Free (block);
  292.     return NULL;
  293. }
  294. break;
  295.       default:
  296. PORT_Assert (0);
  297. PORT_Free (block);
  298. return NULL;
  299.     }
  300.     return block;
  301. }
  302. SECStatus
  303. RSA_FormatBlock(SECItem *result, unsigned modulusLen,
  304. RSA_BlockType blockType, SECItem *data)
  305. {
  306.     /*
  307.      * XXX For now assume that the data length fits in a single
  308.      * XXX encryption block; the ASSERTs below force this.
  309.      * XXX To fix it, each case will have to loop over chunks whose
  310.      * XXX lengths satisfy the assertions, until all data is handled.
  311.      * XXX (Unless RSA has more to say about how to handle data
  312.      * XXX which does not fit in a single encryption block?)
  313.      * XXX And I do not know what the result is supposed to be,
  314.      * XXX so the interface to this function may need to change
  315.      * XXX to allow for returning multiple blocks, if they are
  316.      * XXX not wanted simply concatenated one after the other.
  317.      */
  318.     switch (blockType) {
  319.       case RSA_BlockPrivate0:
  320.       case RSA_BlockPrivate:
  321.       case RSA_BlockPublic:
  322. /*
  323.  * 0x00 || BT || Pad || 0x00 || ActualData
  324.  *
  325.  * The "3" below is the first octet + the second octet + the 0x00
  326.  * octet that always comes just before the ActualData.
  327.  */
  328. PORT_Assert (data->len <= (modulusLen - (3 + RSA_BLOCK_MIN_PAD_LEN)));
  329. result->data = RSA_FormatOneBlock(modulusLen, blockType, data);
  330. if (result->data == NULL) {
  331.     result->len = 0;
  332.     return SECFailure;
  333. }
  334. result->len = modulusLen;
  335. break;
  336.       case RSA_BlockOAEP:
  337. /*
  338.  * 0x00 || BT || M1(Salt) || M2(Pad1||ActualData[||Pad2])
  339.  *
  340.  * The "2" below is the first octet + the second octet.
  341.  * (The other fields do not contain the clear values, but are
  342.  * the same length as the clear values.)
  343.  */
  344. PORT_Assert (data->len <= (modulusLen - (2 + OAEP_SALT_LEN
  345.  + OAEP_PAD_LEN)));
  346. result->data = RSA_FormatOneBlock(modulusLen, blockType, data);
  347. if (result->data == NULL) {
  348.     result->len = 0;
  349.     return SECFailure;
  350. }
  351. result->len = modulusLen;
  352. break;
  353.       case RSA_BlockRaw:
  354. /*
  355.  * Pad || ActualData
  356.  * Pad is zeros. The application is responsible for recovering
  357.  * the actual data.
  358.  */
  359. result->data = (unsigned char*)PORT_ZAlloc(modulusLen);
  360. result->len = modulusLen;
  361. PORT_Memcpy(result->data+(modulusLen-data->len),data->data,data->len);
  362. break;
  363.       default:
  364. PORT_Assert (0);
  365. result->data = NULL;
  366. result->len = 0;
  367. return SECFailure;
  368.     }
  369.     return SECSuccess;
  370. }
  371. /*
  372.  * Takes a formatted block and returns the data part.
  373.  * (This is the inverse of RSA_FormatOneBlock().)
  374.  * In some formats the start of the data is ambiguous;
  375.  * if it is non-zero, expectedLen will disambiguate.
  376.  *
  377.  * NOTE: this routine is not yet used/tested! (XXX please
  378.  * remove this comment once that is no longer the case ;-)
  379.  */
  380. unsigned char *
  381. RSA_DecodeOneBlock(unsigned char *data,
  382.    unsigned int modulusLen,
  383.    unsigned int expectedLen,
  384.    RSA_BlockType *pResultType,
  385.    unsigned int *pResultLen)
  386. {
  387.     RSA_BlockType blockType;
  388.     unsigned char *dp, *res;
  389.     unsigned int i, len, padLen;
  390.     dp = data;
  391.     if (*dp++ != RSA_BLOCK_FIRST_OCTET) {
  392. PORT_SetError (SEC_ERROR_BAD_DATA);
  393. return NULL;
  394.     }
  395.     blockType = (RSA_BlockType)*dp++;
  396.     switch (blockType) {
  397.       case RSA_BlockPrivate0:
  398. if (expectedLen) {
  399.     padLen = modulusLen - expectedLen - 3;
  400.     PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN);
  401.     for (i = 0; i < padLen; i++) {
  402. if (*dp++ != RSA_BLOCK_PRIVATE0_PAD_OCTET)
  403.     break;
  404.     }
  405.     if ((i != padLen) || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) {
  406. PORT_SetError (SEC_ERROR_BAD_DATA);
  407. return NULL;
  408.     }
  409.     dp++;
  410.     len = expectedLen;
  411. } else {
  412.     for (i = 0; i < modulusLen; i++) {
  413. if (*dp++ != RSA_BLOCK_PRIVATE0_PAD_OCTET)
  414.     break;
  415.     }
  416.     if (i == modulusLen) {
  417. PORT_SetError (SEC_ERROR_BAD_DATA);
  418. return NULL;
  419.     }
  420.     if (RSA_BLOCK_PRIVATE0_PAD_OCTET == RSA_BLOCK_AFTER_PAD_OCTET)
  421. dp--;
  422.     padLen = dp - data - 2;
  423.     if ((padLen < RSA_BLOCK_MIN_PAD_LEN)
  424. || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) {
  425. PORT_SetError (SEC_ERROR_BAD_DATA);
  426. return NULL;
  427.     }
  428.     dp++;
  429.     len = modulusLen - (dp - data);
  430. }
  431. res = (unsigned char *) PORT_Alloc(len);
  432. if (res == NULL) {
  433.     return NULL;
  434. }
  435. PORT_Memcpy (res, dp, len);
  436. break;
  437.       case RSA_BlockPrivate:
  438. for (i = 0; i < modulusLen; i++) {
  439.     if (*dp++ != RSA_BLOCK_PRIVATE_PAD_OCTET)
  440. break;
  441. }
  442. if ((i == modulusLen) || (*dp != RSA_BLOCK_AFTER_PAD_OCTET)) {
  443.     PORT_SetError (SEC_ERROR_BAD_DATA);
  444.     return NULL;
  445. }
  446. padLen = dp - data - 2;
  447. dp++;
  448. len = modulusLen - (dp - data);
  449. if ((padLen < RSA_BLOCK_MIN_PAD_LEN) || (expectedLen
  450.  && (expectedLen != len))) {
  451.     PORT_SetError (SEC_ERROR_BAD_DATA);
  452.     return NULL;
  453. }
  454. res = (unsigned char *) PORT_Alloc(len);
  455. if (res == NULL) {
  456.     return NULL;
  457. }
  458. PORT_Memcpy (res, dp, len);
  459. break;
  460.       case RSA_BlockPublic:
  461. for (i = 0; i < modulusLen; i++) {
  462.     if (*dp++ == RSA_BLOCK_AFTER_PAD_OCTET)
  463. break;
  464. }
  465. if (i == modulusLen) {
  466.     PORT_SetError (SEC_ERROR_BAD_DATA);
  467.     return NULL;
  468. }
  469. padLen = dp - data - 2;
  470. dp++;
  471. len = modulusLen - (dp - data);
  472. if ((padLen < RSA_BLOCK_MIN_PAD_LEN) || (expectedLen
  473.  && (expectedLen != len))) {
  474.     PORT_SetError (SEC_ERROR_BAD_DATA);
  475.     return NULL;
  476. }
  477. res = (unsigned char *) PORT_Alloc(len);
  478. if (res == NULL) {
  479.     return NULL;
  480. }
  481. PORT_Memcpy (res, dp, len);
  482. break;
  483.       case RSA_BlockOAEP:
  484. {
  485.     unsigned char *salt, *tmp_res;
  486.     SECStatus rv;
  487.     len = modulusLen - 2 - OAEP_SALT_LEN;
  488.     /*
  489.      * dp points to:
  490.      * Modified2(Salt) || Modified1(PaddedData)
  491.      * To recover Salt we need to XOR it with the low-order hash
  492.      * of Modified1.
  493.      */
  494.     salt = (unsigned char *) PORT_Alloc(OAEP_SALT_LEN);
  495.     if (salt == NULL) {
  496. return NULL;
  497.     }
  498.     PORT_Memcpy (salt, dp, OAEP_SALT_LEN);
  499.     dp += OAEP_SALT_LEN;
  500.     rv = oaep_xor_with_h2 (salt, OAEP_SALT_LEN, dp, len);
  501.     if (rv != SECSuccess) {
  502. PORT_Free (salt);
  503. return NULL;
  504.     }
  505.     if (expectedLen) {
  506. PORT_Assert (expectedLen <= len);
  507. len = expectedLen;
  508.     }
  509.     tmp_res = (unsigned char *) PORT_Alloc(len);
  510.     if (tmp_res == NULL) {
  511. PORT_Free (salt);
  512. return NULL;
  513.     }
  514.     PORT_Memcpy (tmp_res, dp, len);
  515.     rv = oaep_xor_with_h1 (tmp_res, len, salt, OAEP_SALT_LEN);
  516.     PORT_Free (salt);
  517.     if (rv != SECSuccess) {
  518. return NULL;
  519.     }
  520.     for (i = 0; i < OAEP_PAD_LEN; i++) {
  521. if (tmp_res[i] != OAEP_PAD_OCTET) {
  522.     PORT_SetError (SEC_ERROR_BAD_DATA);
  523.     PORT_Free (tmp_res);
  524.     return NULL;
  525. }
  526.     }
  527.     len -= OAEP_PAD_LEN;
  528.     res = (unsigned char *) PORT_Alloc(len);
  529.     if (res == NULL) {
  530. PORT_Free (tmp_res);
  531. return NULL;
  532.     }
  533.     PORT_Memcpy (res, tmp_res + OAEP_PAD_LEN, len);
  534.     PORT_Free (tmp_res);
  535. }
  536. break;
  537.       default:
  538. PORT_SetError (SEC_ERROR_BAD_DATA);
  539. return NULL;
  540.     }
  541.     PORT_Assert (res != NULL);
  542.     *pResultLen = len;
  543.     *pResultType = blockType;
  544.     return res;
  545. }
  546. /* XXX Doesn't set error code */
  547. SECStatus
  548. RSA_Sign(SECKEYLowPrivateKey *key, 
  549.          unsigned char *      output, 
  550.  unsigned int *       output_len,
  551.          unsigned int         maxOutputLen, 
  552.  unsigned char *      input, 
  553.  unsigned int         input_len)
  554. {
  555.     SECStatus     rv          = SECSuccess;
  556.     unsigned int  modulus_len = SECKEY_LowPrivateModulusLen(key);
  557.     SECItem       formatted;
  558.     SECItem       unformatted;
  559.     if (maxOutputLen < modulus_len) 
  560.      return SECFailure;
  561.     PORT_Assert(key->keyType == rsaKey);
  562.     if (key->keyType != rsaKey)
  563.      return SECFailure;
  564.     unformatted.len  = input_len;
  565.     unformatted.data = input;
  566.     formatted.data   = NULL;
  567.     rv = RSA_FormatBlock(&formatted, modulus_len, RSA_BlockPrivate,
  568.  &unformatted);
  569.     if (rv != SECSuccess) 
  570.      goto done;
  571.     rv = RSA_PrivateKeyOp(&key->u.rsa, output, formatted.data);
  572.     *output_len = modulus_len;
  573.     goto done;
  574. done:
  575.     if (formatted.data != NULL) 
  576.      PORT_ZFree(formatted.data, modulus_len);
  577.     return rv;
  578. }
  579. /* XXX Doesn't set error code */
  580. SECStatus
  581. RSA_CheckSign(SECKEYLowPublicKey *key,
  582.               unsigned char *     sign, 
  583.       unsigned int        sign_len, 
  584.       unsigned char *     hash, 
  585.       unsigned int        hash_len)
  586. {
  587.     SECStatus       rv;
  588.     unsigned int    modulus_len = SECKEY_LowPublicModulusLen(key);
  589.     unsigned int    i;
  590.     unsigned char * buffer;
  591.     modulus_len = SECKEY_LowPublicModulusLen(key);
  592.     if (sign_len != modulus_len) 
  593.      goto failure;
  594.     if (hash_len > modulus_len - 8) 
  595.      goto failure;
  596.     PORT_Assert(key->keyType == rsaKey);
  597.     if (key->keyType != rsaKey)
  598.      goto failure;
  599.     buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
  600.     if (!buffer)
  601.      goto failure;
  602.     rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
  603.     if (rv != SECSuccess)
  604. goto loser;
  605.     /*
  606.      * check the padding that was used
  607.      */
  608.     if (buffer[0] != 0 || buffer[1] != 1) 
  609.      goto loser;
  610.     for (i = 2; i < modulus_len - hash_len - 1; i++) {
  611. if (buffer[i] == 0) 
  612.     break;
  613. if (buffer[i] != 0xff) 
  614.     goto loser;
  615.     }
  616.     /*
  617.      * make sure we get the same results
  618.      */
  619.     if (PORT_Memcmp(buffer + modulus_len - hash_len, hash, hash_len) != 0)
  620. goto loser;
  621.     PORT_Free(buffer);
  622.     return SECSuccess;
  623. loser:
  624.     PORT_Free(buffer);
  625. failure:
  626.     return SECFailure;
  627. }
  628. /* XXX Doesn't set error code */
  629. SECStatus
  630. RSA_CheckSignRecover(SECKEYLowPublicKey *key,
  631.                      unsigned char *     data,
  632.                      unsigned int *      data_len, 
  633.      unsigned int        max_output_len, 
  634.      unsigned char *     sign,
  635.      unsigned int        sign_len)
  636. {
  637.     SECStatus       rv;
  638.     unsigned int    modulus_len = SECKEY_LowPublicModulusLen(key);
  639.     unsigned int    i;
  640.     unsigned char * buffer;
  641.     if (sign_len != modulus_len) 
  642.      goto failure;
  643.     PORT_Assert(key->keyType == rsaKey);
  644.     if (key->keyType != rsaKey)
  645.      goto failure;
  646.     buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
  647.     if (!buffer)
  648.      goto failure;
  649.     rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
  650.     if (rv != SECSuccess)
  651.      goto loser;
  652.     *data_len = 0;
  653.     /*
  654.      * check the padding that was used
  655.      */
  656.     if (buffer[0] != 0 || buffer[1] != 1) 
  657.      goto loser;
  658.     for (i = 2; i < modulus_len; i++) {
  659. if (buffer[i] == 0) {
  660.     *data_len = modulus_len - i - 1;
  661.     break;
  662. }
  663. if (buffer[i] != 0xff) 
  664.     goto loser;
  665.     }
  666.     if (*data_len == 0) 
  667.      goto loser;
  668.     if (*data_len > max_output_len) 
  669.      goto loser;
  670.     /*
  671.      * make sure we get the same results
  672.      */
  673.     PORT_Memcpy(data,buffer + modulus_len - *data_len, *data_len);
  674.     PORT_Free(buffer);
  675.     return SECSuccess;
  676. loser:
  677.     PORT_Free(buffer);
  678. failure:
  679.     return SECFailure;
  680. }
  681. /* XXX Doesn't set error code */
  682. SECStatus
  683. RSA_EncryptBlock(SECKEYLowPublicKey *key, 
  684.                  unsigned char *     output, 
  685.  unsigned int *      output_len,
  686.                  unsigned int        max_output_len, 
  687.  unsigned char *     input, 
  688.  unsigned int        input_len)
  689. {
  690.     SECStatus     rv;
  691.     unsigned int  modulus_len = SECKEY_LowPublicModulusLen(key);
  692.     SECItem       formatted;
  693.     SECItem       unformatted;
  694.     formatted.data = NULL;
  695.     if (max_output_len < modulus_len) 
  696.      goto failure;
  697.     PORT_Assert(key->keyType == rsaKey);
  698.     if (key->keyType != rsaKey)
  699.      goto failure;
  700.     unformatted.len  = input_len;
  701.     unformatted.data = input;
  702.     formatted.data   = NULL;
  703.     rv = RSA_FormatBlock(&formatted, modulus_len, RSA_BlockPublic,
  704.  &unformatted);
  705.     if (rv != SECSuccess) 
  706. goto failure;
  707.     rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
  708.     if (rv != SECSuccess) 
  709.      goto failure;
  710.     PORT_ZFree(formatted.data, modulus_len);
  711.     *output_len = modulus_len;
  712.     return SECSuccess;
  713. failure:
  714.     if (formatted.data != NULL) 
  715. PORT_ZFree(formatted.data, modulus_len);
  716.     return SECFailure;
  717. }
  718. /* XXX Doesn't set error code */
  719. SECStatus
  720. RSA_DecryptBlock(SECKEYLowPrivateKey *key, 
  721.                  unsigned char *      output, 
  722.  unsigned int *       output_len,
  723.                  unsigned int         max_output_len, 
  724.  unsigned char *      input, 
  725.  unsigned int         input_len)
  726. {
  727.     SECStatus       rv;
  728.     unsigned int    modulus_len = SECKEY_LowPrivateModulusLen(key);
  729.     unsigned int    i;
  730.     unsigned char * buffer;
  731.     PORT_Assert(key->keyType == rsaKey);
  732.     if (key->keyType != rsaKey)
  733.      goto failure;
  734.     if (input_len != modulus_len)
  735.      goto failure;
  736.     buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
  737.     if (!buffer)
  738.      goto failure;
  739.     rv = RSA_PrivateKeyOp(&key->u.rsa, buffer, input);
  740.     if (rv != SECSuccess) 
  741.      goto loser;
  742.     if (buffer[0] != 0 || buffer[1] != 2) 
  743.      goto loser;
  744.     *output_len = 0;
  745.     for (i = 2; i < modulus_len; i++) {
  746. if (buffer[i] == 0) {
  747.     *output_len = modulus_len - i - 1;
  748.     break;
  749. }
  750.     }
  751.     if (*output_len == 0) 
  752.      goto loser;
  753.     if (*output_len > max_output_len) 
  754.      goto loser;
  755.     PORT_Memcpy(output, buffer + modulus_len - *output_len, *output_len);
  756.     PORT_Free(buffer);
  757.     return SECSuccess;
  758. loser:
  759.     PORT_Free(buffer);
  760. failure:
  761.     return SECFailure;
  762. }
  763. /* XXX Doesn't set error code */
  764. /*
  765.  * added to make pkcs #11 happy
  766.  *   RAW is RSA_X_509
  767.  */
  768. SECStatus
  769. RSA_SignRaw(SECKEYLowPrivateKey *key, 
  770.             unsigned char *      output, 
  771.     unsigned int *       output_len,
  772.             unsigned int         maxOutputLen, 
  773.     unsigned char *      input, 
  774.     unsigned int         input_len)
  775. {
  776.     SECStatus    rv          = SECSuccess;
  777.     unsigned int modulus_len = SECKEY_LowPrivateModulusLen(key);
  778.     SECItem      formatted;
  779.     SECItem      unformatted;
  780.     if (maxOutputLen < modulus_len) 
  781.      return SECFailure;
  782.     PORT_Assert(key->keyType == rsaKey);
  783.     if (key->keyType != rsaKey)
  784.      return SECFailure;
  785.     unformatted.len  = input_len;
  786.     unformatted.data = input;
  787.     formatted.data   = NULL;
  788.     rv = RSA_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
  789.     if (rv != SECSuccess) 
  790.      goto done;
  791.     rv = RSA_PrivateKeyOp(&key->u.rsa, output, formatted.data);
  792.     *output_len = modulus_len;
  793. done:
  794.     if (formatted.data != NULL) 
  795.      PORT_ZFree(formatted.data, modulus_len);
  796.     return rv;
  797. }
  798. /* XXX Doesn't set error code */
  799. SECStatus
  800. RSA_CheckSignRaw(SECKEYLowPublicKey *key,
  801.                  unsigned char *     sign, 
  802.  unsigned int        sign_len, 
  803.  unsigned char *     hash, 
  804.  unsigned int        hash_len)
  805. {
  806.     SECStatus       rv;
  807.     unsigned int    modulus_len = SECKEY_LowPublicModulusLen(key);
  808.     unsigned char * buffer;
  809.     if (sign_len != modulus_len) 
  810.      goto failure;
  811.     if (hash_len > modulus_len) 
  812.      goto failure;
  813.     PORT_Assert(key->keyType == rsaKey);
  814.     if (key->keyType != rsaKey)
  815.      goto failure;
  816.     buffer = (unsigned char *)PORT_Alloc(modulus_len + 1);
  817.     if (!buffer)
  818.      goto failure;
  819.     rv = RSA_PublicKeyOp(&key->u.rsa, buffer, sign);
  820.     if (rv != SECSuccess)
  821. goto loser;
  822.     /*
  823.      * make sure we get the same results
  824.      */
  825.     /* NOTE: should we verify the leading zeros? */
  826.     if (PORT_Memcmp(buffer + (modulus_len-hash_len), hash, hash_len) != 0)
  827. goto loser;
  828.     PORT_Free(buffer);
  829.     return SECSuccess;
  830. loser:
  831.     PORT_Free(buffer);
  832. failure:
  833.     return SECFailure;
  834. }
  835. /* XXX Doesn't set error code */
  836. SECStatus
  837. RSA_CheckSignRecoverRaw(SECKEYLowPublicKey *key,
  838.                         unsigned char *     data,
  839.                         unsigned int *      data_len, 
  840. unsigned int        max_output_len, 
  841. unsigned char *     sign,
  842. unsigned int        sign_len)
  843. {
  844.     SECStatus      rv;
  845.     unsigned int   modulus_len = SECKEY_LowPublicModulusLen(key);
  846.     if (sign_len != modulus_len) 
  847.      goto failure;
  848.     if (max_output_len < modulus_len) 
  849.      goto failure;
  850.     PORT_Assert(key->keyType == rsaKey);
  851.     if (key->keyType != rsaKey)
  852.      goto failure;
  853.     rv = RSA_PublicKeyOp(&key->u.rsa, data, sign);
  854.     if (rv != SECSuccess)
  855. goto failure;
  856.     *data_len = modulus_len;
  857.     return SECSuccess;
  858. failure:
  859.     return SECFailure;
  860. }
  861. /* XXX Doesn't set error code */
  862. SECStatus
  863. RSA_EncryptRaw(SECKEYLowPublicKey *key, 
  864.        unsigned char *     output, 
  865.        unsigned int *      output_len,
  866.                unsigned int        max_output_len, 
  867.        unsigned char *     input, 
  868.        unsigned int        input_len)
  869. {
  870.     SECStatus rv;
  871.     unsigned int  modulus_len = SECKEY_LowPublicModulusLen(key);
  872.     SECItem       formatted;
  873.     SECItem       unformatted;
  874.     formatted.data = NULL;
  875.     if (max_output_len < modulus_len) 
  876.      goto failure;
  877.     PORT_Assert(key->keyType == rsaKey);
  878.     if (key->keyType != rsaKey)
  879.      goto failure;
  880.     unformatted.len  = input_len;
  881.     unformatted.data = input;
  882.     formatted.data   = NULL;
  883.     rv = RSA_FormatBlock(&formatted, modulus_len, RSA_BlockRaw, &unformatted);
  884.     if (rv != SECSuccess)
  885. goto failure;
  886.     rv = RSA_PublicKeyOp(&key->u.rsa, output, formatted.data);
  887.     if (rv != SECSuccess) 
  888.      goto failure;
  889.     PORT_ZFree(formatted.data, modulus_len);
  890.     *output_len = modulus_len;
  891.     return SECSuccess;
  892. failure:
  893.     if (formatted.data != NULL) 
  894. PORT_ZFree(formatted.data, modulus_len);
  895.     return SECFailure;
  896. }
  897. /* XXX Doesn't set error code */
  898. SECStatus
  899. RSA_DecryptRaw(SECKEYLowPrivateKey *key, 
  900.                unsigned char *      output, 
  901.        unsigned int *       output_len,
  902.                unsigned int         max_output_len, 
  903.        unsigned char *      input, 
  904.        unsigned int         input_len)
  905. {
  906.     SECStatus     rv;
  907.     unsigned int  modulus_len = SECKEY_LowPrivateModulusLen(key);
  908.     if (modulus_len <= 0) 
  909.      goto failure;
  910.     if (modulus_len > max_output_len) 
  911.      goto failure;
  912.     PORT_Assert(key->keyType == rsaKey);
  913.     if (key->keyType != rsaKey)
  914.      goto failure;
  915.     if (input_len != modulus_len) 
  916.      goto failure;
  917.     rv = RSA_PrivateKeyOp(&key->u.rsa, output, input);
  918.     if (rv != SECSuccess)
  919.      goto failure;
  920.     *output_len = modulus_len;
  921.     return SECSuccess;
  922. failure:
  923.     return SECFailure;
  924. }