Back to index

lightning-sunbird  0.9+nobinonly
pk11test.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 #define VERSION_MAJOR 1
00037 #define VERSION_MINOR 0
00038 #define VERSION_POINT 7
00039 /* Standard C includes */
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 
00043 /* NSPR includes */
00044 #include <prio.h>
00045 #include <prprf.h>
00046 #include <plarena.h>
00047 #include <prinit.h>
00048 #include <prmem.h>
00049 
00050 /* security includes */
00051 #include <pkcs11t.h>
00052 #include <secmodt.h>
00053 #include <pk11func.h>
00054 #include <secmod.h>
00055 #include <secutil.h>
00056 #include <keyt.h>
00057 
00058 /* replacer header file */
00059 #include "pk11test.h"
00060 
00061 #include "pkcs11.h"
00062 
00063 void SEC_Init(void);
00064 
00065 PRStatus InitCrypto(char*);
00066 int TestUserManagement();
00067 int TestCrypto();
00068 MechInfo* GetMechInfo(CK_MECHANISM_TYPE type);
00069 int TestEncrypt(CK_MECHANISM_TYPE mech);
00070 int TestSign(CK_MECHANISM_TYPE mech);
00071 int TestDigest(CK_MECHANISM_TYPE mech);
00072 int TestHMAC(CK_MECHANISM_TYPE mech);
00073 int TestSymmetricEncrypt(CK_MECHANISM_TYPE mech);
00074 int TestPKEncrypt(CK_MECHANISM_TYPE mech);
00075 
00076 
00077 static char* userpw = NULL;
00078 static int secerror=0;
00079 /* PK11SymKey *symkey=NULL;*/
00080 PK11SlotInfo *slot=NULL;
00081 
00082 /* Errors */
00083 enum {
00084        NO_ERROR_AT_ALL=0,
00085        NO_SUCH_SLOT=1,
00086        KEY_GEN_FAILED,
00087        CREATE_CONTEXT_FAILED,
00088        INTERNAL_RNG_FAILED,
00089        MECH_NOT_FOUND,
00090        INPUT_FILE_ERROR,
00091        KEY_COPY_FAILED,
00092        CIPHER_OP_FAILED,
00093        FINALIZE_FAILED,
00094        RESULTS_DONT_MATCH,
00095        PARAM_GEN_FAILED,
00096        PLAINTEXT_DOESNT_MATCH,
00097        ENCRYPTION_IS_NOOP,
00098        WRAP_PRIVKEY_FAILED,
00099        WRAP_SYMKEY_FAILED,
00100        UNWRAP_SYMKEY_FAILED,
00101        UNWRAPPED_KEY_DOESNT_MATCH,
00102        UNWRAP_PRIVKEY_FAILED,
00103        SIGNATURE_FAILED,
00104        SIGNATURE_DOESNT_VERIFY,
00105        AUTHENTICATION_FAILED,
00106        AUTHENTICATION_SUCCEEDED,
00107        MODDB_ACCESS
00108 };
00109 
00110 static char* errString[] = {
00111        "No error",
00112        "No such slot",
00113        "Failed to generate key",
00114        "Failed to create a cryptographic context",
00115        "Failed to generate random bytes",
00116        "Mechanism was not found",
00117        "Error in input file",
00118        "Failed to copy key from internal to external module",
00119        "Cipher operation failed",
00120        "Cipher finalization failed",
00121        "Internal module produced a different result than the target module",
00122        "Failed to generate cryptographic parameters",
00123        "Recovered plaintext does not match original plaintext",
00124        "Ciphertext is the same as plaintext",
00125        "Unable to wrap private key",
00126        "Unable to wrap symmetric key",
00127        "Unable to unwrap symmetric key",
00128        "Unwrapped key does not match original key",
00129        "Unable to unwrap private key",
00130        "Signing operation failed",
00131        "Incorrect signature: doesn't verify",
00132        "Failed to authenticate to slot",
00133        "Authenticated to slot with incorrect password",
00134        "Unable to access security module database"
00135 };
00136 
00137 /***********************************************************************
00138  *
00139  * R e a d I n p u t F i l e
00140  *
00141  * Read tokenname and module name from the file with the indicated name.
00142  * Pass in the addresses of pointers.  They will be set to point at
00143  * dynamically-allocated memory.
00144  *
00145  * Returns 0 on success, -1 on error with file.
00146  */
00147 int
00148 ReadInputFile(char *filename, char**tokenname, char**moddbname, char **userpw)
00149 {
00150        PRFileDesc* file=NULL;
00151        char readbuf[1025];
00152        int numbytes=0;
00153        char *cp;
00154 
00155        *tokenname = NULL;
00156        *moddbname = NULL;
00157 
00158        /* Open file */
00159        file = PR_Open(filename, PR_RDONLY, 0);
00160        if(!file) {
00161               return -1;
00162        }
00163 
00164        /* Read in everything */
00165        numbytes = PR_Read(file, readbuf, 1024);
00166        if(numbytes==-1) {
00167               goto loser;
00168        }
00169        readbuf[numbytes] = '\0'; /* make sure we're null-terminated */
00170 
00171        /* Get tokenname */
00172        cp = strtok(readbuf, "\r\n");
00173        if(cp == NULL) {
00174               goto loser;
00175        }
00176        *tokenname = PR_Malloc(strlen(cp)+1);
00177        strcpy(*tokenname, cp);
00178 
00179        /* get moddbname */
00180        cp = strtok(NULL, "\r\n");
00181        if(cp == NULL) {
00182               goto loser;
00183        }
00184        *moddbname = PR_Malloc(strlen(cp)+1);
00185        strcpy(*moddbname, cp);
00186 
00187        /* Get module PIN */
00188        cp = strtok(NULL, "\r\n");
00189        if(cp == NULL) {
00190               goto loser;
00191        }
00192        *userpw = PR_Malloc(strlen(cp)+1);
00193        strcpy(*userpw, cp);
00194 
00195        PR_Close(file);
00196        return 0;
00197 
00198 loser:
00199        if(file) {
00200               PR_Close(file);
00201        }
00202        if(*tokenname) {
00203               PR_Free(*tokenname);
00204               *tokenname = NULL;
00205        }
00206        if(*moddbname) {
00207               PR_Free(*moddbname);
00208               *moddbname = NULL;
00209        }
00210        return -1;
00211 }
00212 
00213 static PRBool supplyPassword=PR_TRUE;
00214 char*
00215 PasswordFunc(PK11SlotInfo *slot, PRBool loadcerts, void *wincx)
00216 {
00217        if(supplyPassword) {
00218               /*PR_fprintf(PR_STDOUT, "Feeding password: |%s|\n", userpw);*/
00219               supplyPassword = PR_FALSE;
00220               return PL_strdup(userpw);
00221        } else  {
00222               /*PR_fprintf(PR_STDOUT, "PasswordFunc supplying NULL.\n");*/
00223               return NULL;
00224        }
00225 }
00226        
00227 
00228 /**********************************************************************
00229  *
00230  * m a i n
00231  *
00232  */
00233 int
00234 main(int argc, char *argv[])
00235 {
00236        char *tokenname=NULL;
00237        char *moddbname=NULL;
00238        int errcode;
00239 
00240        if(argc < 3) {
00241               PR_fprintf(PR_STDERR,
00242 "\nPKCS #11 Test Suite Version %d.%d.%d\n\
00243 Usage: pkcs11 testid configfile\n",VERSION_MAJOR,VERSION_MINOR,VERSION_POINT);
00244               return -1;
00245        }
00246 
00247        testId = atoi(argv[1]);
00248        if(ReadInputFile(argv[2], &tokenname, &moddbname, &userpw)) {
00249               errcode = INPUT_FILE_ERROR;
00250               goto loser;
00251        }
00252 
00253        PR_fprintf(PR_STDOUT, "testId=%d\n", testId);
00254        PR_fprintf(PR_STDOUT, "tokenname=%s\n", tokenname);
00255        PR_fprintf(PR_STDOUT, "moddbname=%s\n", moddbname);
00256 
00257        PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
00258 
00259        if( InitCrypto(moddbname) != PR_SUCCESS ) {
00260               errcode = MODDB_ACCESS;
00261               goto loser;
00262        }
00263 
00264        slot = PK11_FindSlotByName(tokenname);
00265        if(!slot) {
00266               errcode = NO_SUCH_SLOT;
00267               goto loser;
00268        }
00269 
00270        if(!REP_USE_CORRECT_PIN && userpw) {
00271               /* don't use the pin passed in */
00272               userpw[0]++;
00273        }
00274        PK11_SetPasswordFunc(PasswordFunc);
00275        if(PK11_NeedLogin(slot)) {
00276               SECStatus result;
00277               supplyPassword = PR_TRUE;
00278               result = PK11_Authenticate(slot, PR_FALSE, NULL);
00279               /* If we just did an invalid login, login correctly so we don't
00280                * cause the token to lock us out */
00281               if(!REP_USE_CORRECT_PIN) {
00282                      userpw[0]--;
00283                      supplyPassword = PR_TRUE;
00284                      PK11_Authenticate(slot, PR_FALSE, NULL);
00285               }
00286               if(REP_USE_CORRECT_PIN && result!=SECSuccess) {
00287                      errcode =  AUTHENTICATION_FAILED;
00288                      goto loser;
00289               } else if(!REP_USE_CORRECT_PIN && result==SECSuccess) {
00290                      errcode = AUTHENTICATION_SUCCEEDED;
00291                      goto loser;
00292               }
00293        }
00294 
00295        errcode = TestCrypto();
00296 
00297 loser:
00298        if(tokenname) {
00299               PR_Free(tokenname); tokenname = NULL;
00300        }
00301        if(moddbname) {
00302               PR_Free(moddbname); moddbname = NULL;
00303        }
00304        if(errcode) {
00305            PR_fprintf(PR_STDOUT, "Exiting with error: %s.\n\n", errString[errcode]);
00306        } else {
00307               PR_fprintf(PR_STDOUT, "Test was successful\n\n");
00308        }
00309        return errcode;
00310 }
00311 
00312 /**********************************************************************
00313  *
00314  * I n i t C r y p t o
00315  *
00316  */
00317 PRStatus
00318 InitCrypto(char *moddbname)
00319 {
00320        SEC_Init();
00321 
00322        if( PR_Access(moddbname, PR_ACCESS_EXISTS) != PR_SUCCESS) {
00323               PR_fprintf(PR_STDERR, "Error: %s does not exist.\n", moddbname);
00324               return PR_FAILURE;
00325        }
00326        if( PR_Access(moddbname, PR_ACCESS_READ_OK) != PR_SUCCESS) {
00327               PR_fprintf(PR_STDERR, "Error: %s is not readable.\n",
00328                      moddbname);
00329               return PR_FAILURE;
00330        }
00331 
00332        SECMOD_init(moddbname);
00333        return PR_SUCCESS;
00334 }
00335 
00336 /**********************************************************************
00337  *
00338  * T e s t C r y p t o
00339  *
00340  */
00341 int
00342 TestCrypto()
00343 {
00344        MechInfo *mechInfo;
00345        int errcode;
00346        unsigned short testcount=0;
00347 
00348        if(!PK11_DoesMechanism(slot, REP_MECHANISM)) {
00349               return 0;
00350        }
00351 
00352        mechInfo = GetMechInfo(REP_MECHANISM);
00353        /*PR_fprintf(PR_STDOUT, "Using mechanism %x.\n", REP_MECHANISM);*/
00354        if(!mechInfo) {
00355               PR_fprintf(PR_STDERR, "Unable to find mech %x\n",
00356                      REP_MECHANISM);
00357               return MECH_NOT_FOUND;
00358        }
00359 
00360        if(mechInfo->op & ENCRYPT_OP) {
00361               testcount++;
00362               errcode = TestEncrypt(REP_MECHANISM);
00363               if(errcode) return errcode;
00364        }
00365 
00366        if(mechInfo->op & SIGN_OP) {
00367               testcount++;
00368               errcode = TestSign(REP_MECHANISM);
00369               if(errcode) return errcode;
00370        }
00371 
00372 #if 0
00373        if(mechInfo->op & DIGEST_OP) {
00374               testcount++;
00375               errcode = TestDigest(REP_MECHANISM);
00376               if(errcode) return errcode;
00377        }
00378 
00379        if(mechInfo->op & HMAC_OP) {
00380               testcount++;
00381               errcode = TestHMAC(REP_MECHANISM);
00382               if(errcode) return errcode;
00383        }
00384 #endif
00385 
00386        return 0;
00387 }
00388 
00389 /**********************************************************************
00390  *
00391  * I s S y m m e t r i c
00392  *
00393  */
00394 int
00395 IsSymmetric(CK_MECHANISM_TYPE mech)
00396 {
00397        switch(mech) {
00398        case CKM_RC2_ECB:
00399        case CKM_RC2_CBC:
00400        case CKM_RC2_CBC_PAD:
00401        case CKM_RC4:
00402        case CKM_RC5_ECB:
00403        case CKM_RC5_CBC:
00404        case CKM_RC5_CBC_PAD:
00405        case CKM_DES_ECB:
00406        case CKM_DES_CBC:
00407        case CKM_DES_CBC_PAD:
00408        case CKM_DES3_ECB:
00409        case CKM_DES3_CBC:
00410        case CKM_DES3_CBC_PAD:
00411        case CKM_CAST_ECB:
00412        case CKM_CAST_CBC:
00413        case CKM_CAST_CBC_PAD:
00414        case CKM_CAST3_ECB:
00415        case CKM_CAST3_CBC:
00416        case CKM_CAST3_CBC_PAD:
00417        case CKM_CAST5_ECB:
00418        case CKM_CAST5_CBC:
00419        case CKM_CAST5_CBC_PAD:
00420        case CKM_IDEA_ECB:
00421        case CKM_IDEA_CBC:
00422        case CKM_IDEA_CBC_PAD:
00423        case CKM_CDMF_ECB:
00424        case CKM_CDMF_CBC:
00425        case CKM_CDMF_CBC_PAD:
00426        case CKM_SKIPJACK_ECB64:
00427        case CKM_SKIPJACK_CBC64:
00428        case CKM_SKIPJACK_OFB64:
00429        case CKM_SKIPJACK_CFB64:
00430        case CKM_SKIPJACK_CFB32:
00431        case CKM_SKIPJACK_CFB16:
00432        case CKM_SKIPJACK_CFB8:
00433        case CKM_BATON_ECB128:
00434        case CKM_BATON_ECB96:
00435        case CKM_BATON_CBC128:
00436        case CKM_BATON_COUNTER:
00437        case CKM_BATON_SHUFFLE:
00438        case CKM_JUNIPER_ECB128:
00439        case CKM_JUNIPER_CBC128:
00440        case CKM_JUNIPER_COUNTER:
00441        case CKM_JUNIPER_SHUFFLE:
00442               return 1;
00443        default:
00444               return 0;
00445        }
00446 }
00447 
00448 /**********************************************************************
00449  *
00450  * T e s t E n c r y p t
00451  *
00452  */
00453 int
00454 TestEncrypt(CK_MECHANISM_TYPE mech)
00455 {
00456 
00457        /*PR_fprintf(PR_STDOUT, "Inside TestEncrypt\n");*/
00458        if(!PK11_DoesMechanism(slot, mech)) {
00459               /* Can't test if the slot doesn't do this mechanism */
00460               PR_fprintf(PR_STDERR, "Slot doesn't do this mechanism.\n");
00461               return 0;
00462        }
00463 
00464        if(IsSymmetric(mech)) {
00465               /*PR_fprintf(PR_STDOUT, "Is a symmetric algorithm\n");*/
00466               return TestSymmetricEncrypt(mech);
00467        } else {
00468               /*PR_fprintf(PR_STDOUT, "Is not a symmetric algorithm\n");*/
00469               return TestPKEncrypt(mech);
00470        }
00471 
00472        return 0;
00473 }
00474 
00475 /**********************************************************************
00476  *
00477  * G e n e r a t e P K P a r a m s
00478  *
00479  */
00480 void*
00481 GeneratePKParams(CK_MECHANISM_TYPE mech)
00482 {
00483 
00484        /* FIPS preprocessor directives for DSA.                        */
00485        #define FIPS_DSA_TYPE                           siBuffer
00486        #define FIPS_DSA_DIGEST_LENGTH                  20  /* 160-bits */
00487        #define FIPS_DSA_SUBPRIME_LENGTH                20  /* 160-bits */
00488        #define FIPS_DSA_SIGNATURE_LENGTH               40  /* 320-bits */
00489        #define FIPS_DSA_PRIME_LENGTH                   64  /* 512-bits */
00490        #define FIPS_DSA_BASE_LENGTH                    64  /* 512-bits */
00491 
00492 
00493        CK_MECHANISM_TYPE keygenMech;
00494        PK11RSAGenParams *rsaparams;
00495        PQGParams *dsa_pqg;
00496        unsigned char *dsa_P = (unsigned char *)
00497                            "\x8d\xf2\xa4\x94\x49\x22\x76\xaa"
00498                            "\x3d\x25\x75\x9b\xb0\x68\x69\xcb"
00499                            "\xea\xc0\xd8\x3a\xfb\x8d\x0c\xf7"
00500                            "\xcb\xb8\x32\x4f\x0d\x78\x82\xe5"
00501                            "\xd0\x76\x2f\xc5\xb7\x21\x0e\xaf"
00502                            "\xc2\xe9\xad\xac\x32\xab\x7a\xac"
00503                            "\x49\x69\x3d\xfb\xf8\x37\x24\xc2"
00504                            "\xec\x07\x36\xee\x31\xc8\x02\x91";
00505        unsigned char *dsa_Q = (unsigned char *)
00506                            "\xc7\x73\x21\x8c\x73\x7e\xc8\xee"
00507                            "\x99\x3b\x4f\x2d\xed\x30\xf4\x8e"
00508                            "\xda\xce\x91\x5f";
00509        unsigned char *dsa_G = (unsigned char *)
00510                            "\x62\x6d\x02\x78\x39\xea\x0a\x13"
00511                            "\x41\x31\x63\xa5\x5b\x4c\xb5\x00"
00512                            "\x29\x9d\x55\x22\x95\x6c\xef\xcb"
00513                            "\x3b\xff\x10\xf3\x99\xce\x2c\x2e"
00514                            "\x71\xcb\x9d\xe5\xfa\x24\xba\xbf"
00515                            "\x58\xe5\xb7\x95\x21\x92\x5c\x9c"
00516                            "\xc4\x2e\x9f\x6f\x46\x4b\x08\x8c"
00517                            "\xc5\x72\xaf\x53\xe6\xd7\x88\x02";
00518 
00519 
00520        keygenMech = PK11_GetKeyGen(mech);
00521 
00522        switch(keygenMech) {
00523        case CKM_RSA_PKCS_KEY_PAIR_GEN:
00524               rsaparams = PR_Malloc(sizeof(PK11RSAGenParams));
00525               rsaparams->keySizeInBits = REP_PK_KEY_SIZE;
00526               rsaparams->pe = 65537L;
00527               return (void*) rsaparams;
00528        case CKM_ECDSA_KEY_PAIR_GEN:
00529        case CKM_DSA_KEY_PAIR_GEN:
00530 
00531               /* Allocate PQG memory */
00532               dsa_pqg = PORT_ZAlloc(sizeof(PQGParams));
00533               dsa_pqg->prime.data = (unsigned char*)
00534                      PORT_ZAlloc(FIPS_DSA_PRIME_LENGTH);
00535               dsa_pqg->subPrime.data = (unsigned char*)
00536                      PORT_ZAlloc(FIPS_DSA_SUBPRIME_LENGTH);
00537               dsa_pqg->base.data = (unsigned char*)
00538                      PORT_ZAlloc(FIPS_DSA_BASE_LENGTH);
00539 
00540               dsa_pqg->prime.type = FIPS_DSA_TYPE;
00541               PORT_Memcpy(dsa_pqg->prime.data, dsa_P, FIPS_DSA_PRIME_LENGTH);
00542               dsa_pqg->prime.len = FIPS_DSA_PRIME_LENGTH;
00543 
00544               dsa_pqg->subPrime.type = FIPS_DSA_TYPE;
00545               PORT_Memcpy( dsa_pqg->subPrime.data, dsa_Q,
00546                      FIPS_DSA_SUBPRIME_LENGTH );
00547               dsa_pqg->subPrime.len = FIPS_DSA_SUBPRIME_LENGTH;
00548 
00549               dsa_pqg->base.type = FIPS_DSA_TYPE;
00550               PORT_Memcpy( dsa_pqg->base.data, dsa_G, FIPS_DSA_BASE_LENGTH );
00551               dsa_pqg->base.len = FIPS_DSA_BASE_LENGTH;
00552 
00553               return (void*) dsa_pqg;
00554 
00555        case CKM_DH_PKCS_KEY_PAIR_GEN:
00556        case CKM_KEA_KEY_PAIR_GEN:
00557        default:
00558               return NULL;
00559        }
00560        return NULL;
00561 }
00562 
00563 /**********************************************************************
00564  *
00565  * F r e e P K P a r a m s
00566  *
00567  */
00568 void
00569 FreePKParams(void* p, CK_MECHANISM_TYPE mech)
00570 {
00571 
00572        switch(PK11_GetKeyGen(mech)) {
00573        case CKM_RSA_PKCS_KEY_PAIR_GEN:
00574               PR_Free( (PK11RSAGenParams*)p);
00575               break;
00576        case CKM_ECDSA_KEY_PAIR_GEN:
00577        case CKM_DSA_KEY_PAIR_GEN:
00578               PR_Free( (PQGParams*)p);
00579               break;
00580        }
00581 }
00582 
00583 
00584 /**********************************************************************
00585  *
00586  * T e s t P K E n c r y p t
00587  *
00588  */
00589 int
00590 TestPKEncrypt(CK_MECHANISM_TYPE mech)
00591 {
00592        PK11SlotInfo *internal;
00593        SECStatus status;
00594        int errcode;
00595        SECItem *kgparams;
00596        SECKEYPublicKey *pubk=NULL;
00597        SECKEYPrivateKey *refPrivk=NULL, *testPrivk=NULL;
00598        PK11SymKey *refSymKey=NULL, *testSymKey=NULL, *recoveredSymKey=NULL;
00599        SECItem refWrappedKey, testWrappedKey;
00600        SECItem *refSymkeyData=NULL, *testSymkeyData=NULL;
00601        SECItem wrapParams;
00602        int testSymKeySize;
00603     CK_ATTRIBUTE_TYPE usages[] = { CKA_UNWRAP };
00604     int usageCount = 1;
00605 
00606        wrapParams.data = "aaaaaaaa";
00607        wrapParams.len = 8;
00608 
00609        refWrappedKey.len = 1024;
00610        refWrappedKey.data = PR_Malloc(1024);
00611        testWrappedKey.len = 1024;
00612        testWrappedKey.data = PR_Malloc(1024);
00613 
00614        internal = PK11_GetInternalSlot();
00615 
00616        /* Generate keygen parameter */
00617        kgparams = GeneratePKParams(mech);
00618        if(!kgparams) {
00619               errcode = PARAM_GEN_FAILED;
00620               goto loser;
00621        }
00622 
00623     /*
00624      * Generate the keypair, either on the target module or on the internal
00625      * module.
00626      */
00627        if(REP_KEYGEN_ON_TARGET) {
00628               refPrivk = PK11_GenerateKeyPair(slot, PK11_GetKeyGen(mech),
00629                      kgparams, &pubk,
00630                      (slot==internal) ? PR_FALSE : PR_TRUE /*isPerm*/,
00631                      PR_FALSE /*isSensitive*/,
00632                      NULL/*wincx*/);
00633        } else {
00634               refPrivk = PK11_GenerateKeyPair(internal, PK11_GetKeyGen(mech),
00635                      kgparams, &pubk,
00636                      PR_FALSE/*isPerm*/, PR_FALSE /*isSensitive*/,
00637                      NULL/*wincx*/);
00638        }
00639        if(!refPrivk) {
00640               secerror = PORT_GetError();
00641               errcode = KEY_GEN_FAILED;
00642               goto loser;
00643        }
00644 
00645        /*
00646         * Generate symmetric key, either on the target module or on the internal
00647      * module.
00648         */
00649        if(REP_KEYGEN_ON_TARGET) {
00650               refSymKey = PK11_KeyGen(slot, CKM_DES_CBC_PAD, NULL,
00651                      REP_SYMKEY_SIZE, NULL);
00652        } else {
00653               refSymKey = PK11_KeyGen(internal, CKM_DES_CBC_PAD, NULL,
00654                      REP_SYMKEY_SIZE, NULL);
00655        }
00656        if(!refSymKey) {
00657               secerror = PORT_GetError();
00658               errcode = KEY_GEN_FAILED;
00659               goto loser;
00660        }
00661 
00662        /*
00663      * If we generated the keys on the internal module, we have to
00664      * transfer them from the internal module to the target module, unless
00665      * the target module is the internal module.
00666         */
00667        if( (slot != internal) && !REP_KEYGEN_ON_TARGET) {
00668               SECItem empty;
00669               SECItem label;
00670               empty.len=0;
00671               empty.data=NULL;
00672               label.data = "foobar";
00673               label.len = 6;
00674 
00675               /* Copy the symmetric key to the target token*/
00676               testSymKey = pk11_CopyToSlot(slot,
00677                                         CKM_DES_CBC_PAD,
00678                                         CKA_UNWRAP,
00679                                         refSymKey);
00680               if(testSymKey==NULL) {
00681                      secerror = PORT_GetError();
00682                      errcode = KEY_COPY_FAILED;
00683                      goto loser;
00684               }
00685 
00686               /* Copy the private key to the target token */
00687               status = PK11_WrapPrivKey(internal,
00688                                      refSymKey,
00689                                      refPrivk,
00690                                      CKM_DES_CBC_PAD,
00691                                      &wrapParams,
00692                                      &refWrappedKey,
00693                                      NULL /*wincx*/);
00694               if(status != SECSuccess) {
00695                      secerror = PORT_GetError();
00696                      errcode = WRAP_PRIVKEY_FAILED;
00697                      goto loser;
00698               }
00699 
00700               testPrivk = PK11_UnwrapPrivKey(slot,
00701                                            testSymKey,
00702                                            CKM_DES_CBC_PAD,
00703                                            &wrapParams,
00704                                            &refWrappedKey,
00705                                            &label /*label*/,
00706                                            &empty /*ID Value*/,
00707                                            PR_TRUE /*perm*/,
00708                                            PR_TRUE /*sensitive*/,
00709                          PK11_GetKeyType(mech, 0),
00710                          usages, usageCount,
00711                                            NULL /*wincx*/);
00712               if(testPrivk==NULL) {
00713                      secerror = PORT_GetError();
00714                      errcode = UNWRAP_PRIVKEY_FAILED;
00715                      goto loser;
00716               }
00717        } else {
00718               testPrivk=refPrivk; refPrivk = NULL;
00719               testSymKey=refSymKey; refSymKey = NULL;
00720        }
00721 
00722        /* Wrap the symmetric key with the public key */
00723     /* !!! Which mech do we use here, the symmetric or the PK? */
00724        status = PK11_PubWrapSymKey(mech, pubk, testSymKey, &testWrappedKey);
00725        if(status != SECSuccess) {
00726               secerror = PORT_GetError();
00727               errcode = WRAP_SYMKEY_FAILED;
00728               goto loser;
00729        }
00730        testSymKeySize = PK11_GetKeyLength(testSymKey);
00731 
00732        /*
00733         * Unless we are testing the internal slot, do the same wrap operation
00734         * on the internal slot and compare with the wrap done on the module
00735         * under test.  If we did the keygen on the target module, we don't
00736      * have the keys on the internal module so we can't compare.
00737         */
00738        if( (slot != internal) && !REP_KEYGEN_ON_TARGET) {
00739               status = PK11_PubWrapSymKey(mech, pubk, refSymKey,
00740                             &refWrappedKey);
00741               if(status != SECSuccess) {
00742                      secerror = PORT_GetError();
00743                      errcode = WRAP_SYMKEY_FAILED;
00744                      goto loser;
00745               }
00746 
00747               if( (testWrappedKey.len != refWrappedKey.len) ||
00748                   memcmp(testWrappedKey.data, refWrappedKey.data, 
00749                      testWrappedKey.len) ) {
00750                      /* Wrapped Keys don't match */
00751                      /* !!! There's random data in these encryptions, so they'll never
00752              * match. */
00753                      /*errcode = RESULTS_DONT_MATCH;*/
00754                      /*goto loser;*/
00755               }
00756        }
00757 
00758        /* Get the data of the symmetric key */
00759     /* Extracting the key value may not work, depending on the token.  If
00760      * it doesn't work, we won't be able to do the comparison later */
00761     PK11_ExtractKeyValue(testSymKey);
00762        testSymkeyData = PK11_GetKeyData(testSymKey);
00763     if(testSymkeyData->data == NULL) {
00764         /* couldn't extract key data */
00765         testSymkeyData = NULL;
00766     } else {
00767            testSymkeyData = SECITEM_DupItem(testSymkeyData);
00768     }
00769 
00770        /* Destroy the symmetric key everywhere */
00771        if(refSymKey) {
00772               PK11_FreeSymKey(refSymKey); refSymKey = NULL;
00773        }
00774        if(testSymKey) {
00775               PK11_FreeSymKey(testSymKey); testSymKey = NULL;
00776        }
00777 
00778        /*
00779         * Unwrap the key and make sure we get the same thing back. Can only
00780      * do this if we were able to get the key data from the test token.
00781         */
00782     if(testSymkeyData != NULL) {
00783            refSymKey = PK11_PubUnwrapSymKey(testPrivk, &testWrappedKey,
00784                          CKM_DES_CBC_PAD, CKA_WRAP, testSymKeySize);
00785            if(refSymKey==NULL) {
00786                   secerror = PORT_GetError();
00787                   errcode = UNWRAP_SYMKEY_FAILED;
00788                   goto loser;
00789            }
00790         /* We should always be able to get the key data from the internal
00791          * module */
00792               PK11_ExtractKeyValue(refSymKey);
00793            refSymkeyData = PK11_GetKeyData(refSymKey);
00794         PR_ASSERT(refSymkeyData!=NULL && refSymkeyData->data!=NULL);
00795         PR_ASSERT(testSymkeyData!=NULL && testSymkeyData->data!=NULL);
00796            if(SECITEM_CompareItem(refSymkeyData, testSymkeyData) != SECEqual) {
00797                   errcode = UNWRAPPED_KEY_DOESNT_MATCH;
00798                   goto loser;
00799            }
00800     }
00801 
00802 #ifdef DEBUG
00803        PR_fprintf(PR_STDOUT, "Successfully finished TestPKEncrypt!\n");
00804 #endif
00805 
00806        errcode = 0;
00807 
00808 loser:
00809        if(refPrivk) {
00810               SECKEY_DestroyPrivateKey(refPrivk);
00811        }
00812        SECITEM_FreeItem(&refWrappedKey, PR_FALSE);
00813        SECITEM_FreeItem(&testWrappedKey, PR_FALSE);
00814        if(refSymkeyData) {
00815               /* do nothing, it's a copy */
00816        }
00817        if(testSymkeyData) {
00818               SECITEM_FreeItem(testSymkeyData, PR_TRUE);
00819        }
00820        if(pubk) {
00821               SECKEY_DestroyPublicKey(pubk);
00822        }
00823        if(testPrivk) {
00824               SECKEY_DestroyPrivateKey(testPrivk);
00825        }
00826        if(refSymKey) {
00827               PK11_FreeSymKey(refSymKey);
00828        } 
00829        if(testSymKey) {
00830               PK11_FreeSymKey(testSymKey);
00831        }
00832        if(recoveredSymKey) {
00833               PK11_FreeSymKey(recoveredSymKey);
00834        }
00835        return errcode;
00836        
00837 
00838 }
00839 
00840 /**********************************************************************
00841  *
00842  * T e s t S y m m e t r i c E n c r y p t
00843  *
00844  */
00845 int
00846 TestSymmetricEncrypt(CK_MECHANISM_TYPE mech)
00847 {
00848        PK11Context *refcontext=NULL, *testcontext=NULL;
00849        PK11SlotInfo *internal;
00850        SECStatus status;
00851        PK11SymKey* intkey=NULL, *extkey=NULL;
00852        int errcode;
00853        unsigned char *ptext=NULL;
00854        int maxclen = REP_PLAINTEXT_LEN + 128;
00855        unsigned char *refctext=NULL, *testctext=NULL;
00856        int refclen, testclen;
00857        unsigned char *recovered=NULL;
00858        int reclen;
00859        SECItem iv, *param=NULL;
00860 
00861        internal = PK11_GetInternalSlot();
00862 
00863        ptext = PR_Malloc(REP_PLAINTEXT_LEN);
00864        refctext = PR_Malloc(maxclen);
00865        testctext = PR_Malloc(maxclen);
00866        recovered = PR_Malloc(maxclen);
00867 
00868     /* Generate random plaintext */
00869        status = RNG_GenerateGlobalRandomBytes(ptext, REP_PLAINTEXT_LEN);
00870        if(status != SECSuccess) {
00871               errcode = INTERNAL_RNG_FAILED;
00872               goto loser;
00873        }
00874 
00875        /* Generate mechanism parameter */
00876        iv.len = 8;
00877        iv.data = "aaaaaaaa"; /* !!! does this need to be random? Maybe a
00878                             * replacer variable ? */
00879        param = PK11_ParamFromIV(mech, &iv);
00880        if(!param) {
00881               errcode = PARAM_GEN_FAILED;
00882               goto loser;
00883        }
00884 
00885        /*
00886      * Generate the key, either on the target module or the internal module.
00887         */
00888        if(REP_KEYGEN_ON_TARGET) {
00889               intkey = PK11_KeyGen(slot, mech, NULL, REP_SYMKEY_SIZE,
00890                      NULL);
00891        } else {
00892               intkey = PK11_KeyGen(internal, mech, NULL, REP_SYMKEY_SIZE,
00893                      NULL);
00894        }
00895        if(!intkey) {
00896               secerror = PORT_GetError();
00897               errcode = KEY_GEN_FAILED;
00898               goto loser;
00899        }
00900 
00901        if( (slot != internal) && !REP_KEYGEN_ON_TARGET) {
00902               /* Copy the key to the target token if it isn't there already */
00903               extkey = pk11_CopyToSlot(slot, mech, CKA_ENCRYPT, intkey);
00904               if(!extkey) {
00905                      secerror = PORT_GetError();
00906                      errcode = KEY_COPY_FAILED;
00907                      goto loser;
00908               }
00909        } else {
00910               extkey = intkey;
00911               intkey = NULL;
00912        }
00913 
00914        /* Create an encryption context */
00915        testcontext = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT, extkey,
00916                                           param);
00917        if(!testcontext) {
00918               secerror = PORT_GetError();
00919               errcode = CREATE_CONTEXT_FAILED;
00920               goto loser;
00921        }
00922 
00923        /* Do the encryption */
00924        status = PK11_CipherOp(testcontext, testctext, &testclen,
00925                             maxclen, ptext, REP_PLAINTEXT_LEN);
00926        if(status != SECSuccess) {
00927               secerror = PORT_GetError();
00928               errcode = CIPHER_OP_FAILED;
00929               goto loser;
00930        }
00931        status = PK11_Finalize(testcontext);
00932        if(status != SECSuccess) {
00933               secerror = PORT_GetError();
00934               errcode = FINALIZE_FAILED;
00935               goto loser;
00936        }
00937 
00938        /* Free the encryption context */
00939        PK11_DestroyContext(testcontext, PR_TRUE /*freeit*/);
00940        testcontext = NULL;
00941 
00942        /* Make sure the encryption did something */
00943        if(!memcmp(ptext, testctext,
00944               REP_PLAINTEXT_LEN > testclen ? testclen : REP_PLAINTEXT_LEN)) {
00945               errcode = ENCRYPTION_IS_NOOP;
00946               goto loser;
00947        }
00948 
00949     /*
00950         * Now do everything on the internal module and compare the results. 
00951      * If the key was generated on the target module, it doesn't exist on
00952      * the internal module so we can't compare.
00953      */
00954        if( (slot != internal) && !REP_KEYGEN_ON_TARGET) {
00955               /* Create encryption context */
00956               refcontext = PK11_CreateContextBySymKey(mech, CKA_ENCRYPT,
00957                      intkey, param);
00958               if(!refcontext) {
00959                      secerror = PORT_GetError();
00960                      errcode = CREATE_CONTEXT_FAILED;
00961                      goto loser;
00962               }
00963 
00964               /* Perform the encryption */
00965               status = PK11_CipherOp(refcontext, refctext, &refclen,
00966                             maxclen, ptext, REP_PLAINTEXT_LEN);
00967               if(status != SECSuccess) {
00968                      secerror = PORT_GetError();
00969                      errcode = CIPHER_OP_FAILED;
00970                      goto loser;
00971               }
00972               status = PK11_Finalize(refcontext);
00973               if(status != SECSuccess) {
00974                      secerror = PORT_GetError();
00975                      errcode = FINALIZE_FAILED;
00976                      goto loser;
00977               }
00978 
00979               /* Free the context */
00980               PK11_DestroyContext(refcontext, PR_TRUE /*freeit*/);
00981               refcontext = NULL;
00982 
00983 
00984               /* Compare the ciphertext from the target module and the
00985                * internal module
00986                */
00987               if( (testclen != refclen) ||
00988                 (memcmp(testctext, refctext, testclen)) ) {
00989                      errcode = RESULTS_DONT_MATCH;
00990                      goto loser;
00991               }
00992        }
00993 
00994        /*
00995         * Decrypt the ciphertext and make sure we get back the original
00996         * ptext
00997         */
00998 
00999        /* Create the decryption context */
01000        testcontext = PK11_CreateContextBySymKey(mech, CKA_DECRYPT, extkey,
01001                             param);
01002        if(!testcontext) {
01003               secerror = PORT_GetError();
01004               errcode = CREATE_CONTEXT_FAILED;
01005               goto loser;
01006        }
01007 
01008        /* Do the decryption */
01009        status = PK11_CipherOp(testcontext, recovered, &reclen,
01010                             maxclen, testctext, testclen);
01011        if(status != SECSuccess) {
01012               secerror = PORT_GetError();
01013               errcode = CIPHER_OP_FAILED;
01014               goto loser;
01015        }
01016        status = PK11_Finalize(testcontext);
01017        if(status != SECSuccess) {
01018               secerror = PORT_GetError();
01019               errcode = FINALIZE_FAILED;
01020               goto loser;
01021        }
01022 
01023 
01024        /* Free the encryption context */
01025        PK11_DestroyContext(testcontext, PR_TRUE /*freeit*/);
01026        testcontext = NULL;
01027 
01028 
01029        /* Compare the recovered text to the plaintext */
01030        if( (reclen != REP_PLAINTEXT_LEN) || 
01031               (memcmp(recovered, ptext, reclen)) ) {
01032                      errcode = PLAINTEXT_DOESNT_MATCH;
01033                      goto loser;
01034        }
01035        
01036 
01037 #ifdef DEBUG
01038        PR_fprintf(PR_STDOUT, "Successfully finished TestSymmetricEncrypt!\n");
01039 #endif
01040 
01041        errcode = 0;
01042 
01043 loser:
01044        if(ptext) {
01045               PR_Free(ptext); ptext = NULL;
01046        }
01047        if(refctext) {
01048               PR_Free(refctext); refctext = NULL;
01049        }
01050        if(testctext) {
01051               PR_Free(testctext); testctext = NULL;
01052        }
01053        if(intkey) {
01054               PK11_FreeSymKey(intkey); intkey = NULL;
01055        }
01056        if(extkey) {
01057               PK11_FreeSymKey(extkey); extkey = NULL;
01058        }
01059        if(testcontext) {
01060               PK11_DestroyContext(testcontext, PR_TRUE /*freeit*/);
01061        }
01062        if(refcontext) {
01063               PK11_DestroyContext(refcontext, PR_TRUE /*freeit*/);
01064        }
01065        if(param) {
01066               SECITEM_FreeItem(param, PR_TRUE);
01067               param = NULL;
01068        }
01069        if(recovered) {
01070               PR_Free(recovered); recovered = NULL;
01071        }
01072        return errcode;
01073 }
01074 
01075 /**********************************************************************
01076  *
01077  * T e s t S i g n
01078  *
01079  */
01080 int
01081 TestSign(CK_MECHANISM_TYPE mech)
01082 {
01083        PK11SlotInfo *internal;
01084        SECStatus status;
01085        int errcode;
01086        SECItem *kgparams;
01087        SECKEYPublicKey *pubk=NULL;
01088        SECKEYPrivateKey *refPrivk=NULL, *testPrivk=NULL;
01089        PK11SymKey *refSymKey=NULL, *testSymKey=NULL, *recoveredSymKey=NULL;
01090        SECItem refWrappedKey, testWrappedKey;
01091        SECItem ptext, refSignature, testSignature;
01092        SECItem wrapParam;
01093     CK_ATTRIBUTE_TYPE usages[] = { CKA_SIGN };
01094     int usageCount = 1;
01095 
01096        refWrappedKey.len = 1024;
01097        refWrappedKey.data = PR_Malloc(1024);
01098        testWrappedKey.len = 1024;
01099        testWrappedKey.data = PR_Malloc(1024);
01100        refSignature.len = 1024;
01101        refSignature.data = PR_Malloc(1024);
01102        testSignature.len = 1024;
01103        testSignature.data = PR_Malloc(1024);
01104        wrapParam.data = "aaaaaaaa";
01105        wrapParam.len = 8;
01106 
01107        internal = PK11_GetInternalSlot();
01108 
01109        /* Generate random ptext */
01110        ptext.data = PR_Malloc(20);
01111        ptext.len = 20;
01112        status = RNG_GenerateGlobalRandomBytes(ptext.data, 8);
01113        if(status != SECSuccess) {
01114               errcode = INTERNAL_RNG_FAILED;
01115               goto loser;
01116        }
01117 
01118        /* Generate keygen parameter */
01119        kgparams = GeneratePKParams(mech);
01120        if(!kgparams) {
01121               errcode = PARAM_GEN_FAILED;
01122               goto loser;
01123        }
01124 
01125        /*
01126      * Generate the keypair, on the target module or the internal module.
01127         */
01128        if(REP_KEYGEN_ON_TARGET) {
01129               refPrivk = PK11_GenerateKeyPair(slot, PK11_GetKeyGen(mech),
01130                      kgparams, &pubk, (slot==internal) ? PR_FALSE :
01131                      PR_TRUE /*isPerm*/,
01132                      PR_FALSE /*isSensitive*/, NULL/*wincx*/);
01133        } else {
01134               refPrivk = PK11_GenerateKeyPair(internal, PK11_GetKeyGen(mech),
01135                      kgparams, &pubk, PR_FALSE /*isPerm*/,
01136                      PR_FALSE /*isSensitive*/, NULL/*wincx*/);
01137        }
01138        if(!refPrivk) {
01139               secerror = PORT_GetError();
01140               errcode = KEY_GEN_FAILED;
01141               goto loser;
01142        }
01143 
01144        /*
01145         * Generate symmetric key, on the target module or the internal module.
01146         */
01147        if(REP_KEYGEN_ON_TARGET) {
01148               refSymKey = PK11_KeyGen(slot, CKM_DES_CBC_PAD, NULL,
01149                      REP_SYMKEY_SIZE, NULL);
01150        } else {
01151               refSymKey = PK11_KeyGen(internal, CKM_DES_CBC_PAD, NULL,
01152                      REP_SYMKEY_SIZE, NULL);
01153        }
01154        if(!refSymKey) {
01155               secerror = PORT_GetError();
01156               errcode = KEY_GEN_FAILED;
01157               goto loser;
01158        }
01159 
01160        /*
01161      * If the key was generated on the internal module, copy it to the
01162      * target module, unless the target module is the internal module.
01163         */
01164        if( (slot != internal) && !REP_KEYGEN_ON_TARGET) {
01165               SECItem empty;
01166               SECItem label;
01167               SECItem *pubValue;
01168               empty.len=0;
01169               empty.data=NULL;
01170               label.len=6;
01171               label.data = "foobar";
01172 
01173               /* Copy the symmetric key to the target token*/
01174               testSymKey = pk11_CopyToSlot(slot,
01175                                         CKM_DES_CBC_PAD,
01176                                         CKA_WRAP,
01177                                         refSymKey);
01178               if(testSymKey==NULL) {
01179                      secerror = PORT_GetError();
01180                      errcode = KEY_COPY_FAILED;
01181                      goto loser;
01182               }
01183 
01184               /* Copy the private key to the target token */
01185               status = PK11_WrapPrivKey(internal,
01186                                      refSymKey,
01187                                      refPrivk,
01188                                      CKM_DES_CBC_PAD,
01189                                      &wrapParam,
01190                                      &refWrappedKey,
01191                                      NULL /*wincx*/);
01192               if(status != SECSuccess) {
01193                      secerror = PORT_GetError();
01194                      errcode = WRAP_PRIVKEY_FAILED;
01195                      goto loser;
01196               }
01197 
01198               switch(pubk->keyType) {
01199               case dsaKey:
01200                      pubValue = SECITEM_DupItem(&pubk->u.dsa.publicValue);
01201                      break;
01202               case rsaKey:
01203                      pubValue = SECITEM_DupItem(&pubk->u.rsa.modulus);
01204                      break;
01205               default:
01206                      pubValue = NULL;
01207               }
01208               testPrivk = PK11_UnwrapPrivKey(slot,
01209                                            testSymKey,
01210                                            CKM_DES_CBC_PAD,
01211                                            &wrapParam,
01212                                            &refWrappedKey,
01213                                            &label /*label*/,
01214                                            pubValue /*ID Value*/,
01215                                            PR_TRUE /*perm*/,
01216                                            PR_TRUE /*sensitive*/,
01217                          PK11_GetKeyType(mech, 0),
01218                          usages, usageCount,
01219                                            NULL /*wincx*/);
01220               if(pubValue) {
01221                      SECITEM_FreeItem(pubValue, PR_TRUE);
01222                      pubValue = NULL;
01223               }
01224               if(testPrivk==NULL) {
01225                      secerror = PORT_GetError();
01226                      errcode = UNWRAP_PRIVKEY_FAILED;
01227                      goto loser;
01228               }
01229        } else {
01230               testPrivk=refPrivk; refPrivk = NULL;
01231               testSymKey=refSymKey; refSymKey = NULL;
01232        }
01233 
01234        /* Sign the data with the private key */
01235        status = PK11_Sign(testPrivk, &testSignature, &ptext);
01236        if(status != SECSuccess) {
01237               secerror = PORT_GetError();
01238               errcode = SIGNATURE_FAILED;
01239               goto loser;
01240        }
01241 
01242        /*
01243         * Unless we are testing the internal slot, do the same wrap operation
01244         * on the internal slot and compare with the signature done on the
01245         * module under test
01246         * Also, DSA signatures contain random data, so comparing them
01247         * is useless (I suppose if they are the same something is wrong!).
01248         */
01249        if( (slot != internal) && !REP_KEYGEN_ON_TARGET
01250               && mech != CKM_DSA && mech != CKM_DSA_SHA1) {
01251               status = PK11_Sign(refPrivk, &refSignature, &ptext);
01252               if(status != SECSuccess) {
01253                      secerror = PORT_GetError();
01254                      errcode = SIGNATURE_FAILED;
01255                      goto loser;
01256               }
01257 
01258               if( SECITEM_CompareItem(&refSignature, &testSignature)
01259                      !=  SECEqual) {
01260                      errcode = RESULTS_DONT_MATCH;
01261                      goto loser;
01262               }
01263        }
01264 
01265 
01266        /*
01267         * Verify the signature.
01268         */
01269        status = PK11_Verify(pubk, &testSignature, &ptext, NULL /*wincx*/);
01270        if(status != SECSuccess) {
01271               secerror = PORT_GetError();
01272               errcode = SIGNATURE_DOESNT_VERIFY;
01273               goto loser;
01274        }
01275 
01276 
01277 #ifdef DEBUG
01278        PR_fprintf(PR_STDOUT, "Successfully finished TestSign!\n");
01279 #endif
01280 
01281        errcode = 0;
01282 
01283 loser:
01284        SECITEM_FreeItem(&refWrappedKey, PR_FALSE);
01285        SECITEM_FreeItem(&testWrappedKey, PR_FALSE);
01286        SECITEM_FreeItem(&ptext, PR_FALSE);
01287        SECITEM_FreeItem(&refSignature, PR_FALSE);
01288        SECITEM_FreeItem(&testSignature, PR_FALSE);
01289        if(refPrivk) {
01290               SECKEY_DestroyPrivateKey(refPrivk);
01291        }
01292        if(pubk) {
01293               SECKEY_DestroyPublicKey(pubk);
01294        }
01295        if(testPrivk) {
01296               SECKEY_DestroyPrivateKey(testPrivk);
01297        }
01298        if(refSymKey) {
01299               PK11_FreeSymKey(refSymKey);
01300        } 
01301        if(testSymKey) {
01302               PK11_FreeSymKey(testSymKey);
01303        }
01304        if(recoveredSymKey) {
01305               PK11_FreeSymKey(recoveredSymKey);
01306        }
01307        return errcode;
01308        
01309 
01310 }
01311 
01312 /**********************************************************************
01313  *
01314  * T e s t D i g e s t
01315  *
01316  */
01317 int
01318 TestDigest(CK_MECHANISM_TYPE mech)
01319 {
01320        return 0;
01321 }
01322 
01323 /**********************************************************************
01324  *
01325  * T e s t H M A C
01326  *
01327  */
01328 int
01329 TestHMAC(CK_MECHANISM_TYPE mech)
01330 {
01331        return 0;
01332 }
01333 
01334 /**********************************************************************
01335  *
01336  * G e t M e c h I n f o
01337  *
01338  */
01339 MechInfo*
01340 GetMechInfo(CK_MECHANISM_TYPE type)
01341 {
01342        /* mechInfo array is sorted by type, so we can do a binary search
01343           l is the left-most possible matching index
01344           r is the rightmost possible matching index
01345           mid is approximately the middle point between l and r */
01346        int l, r, mid;
01347 
01348        l = 0; r = numMechs-1;
01349 
01350        while(l <= r) {
01351               mid = (l+r)/2;
01352               if(mechInfo[mid].type == type) {
01353                      return &(mechInfo[mid]);
01354               } else if(mechInfo[mid].type < type) {
01355                      l = mid+1;
01356               } else {
01357                      r = mid-1;
01358               }
01359        }
01360 
01361        /* If l > r, the pointers have crossed without finding the element. */
01362        return NULL;
01363 }