Exemple #1
0
static CSSM_RETURN sigVerify(CSSM_CSP_HANDLE cspHandle,
	uint32 algorithm,					// CSSM_ALGID_SHA1WithRSA, etc.
	CSSM_KEY_PTR key,					// public key
	const CSSM_DATA *text,
	const CSSM_DATA *sig)
{
	CSSM_CC_HANDLE	sigHand;
	CSSM_RETURN		crtn;
	
	crtn = CSSM_CSP_CreateSignatureContext(cspHandle,
		algorithm,
		NULL,				// passPhrase
		key,
		&sigHand);
	if(crtn) {
		return crtn;
	}
	crtn = CSSM_VerifyData(sigHand,
		text,
		1,
		CSSM_ALGID_NONE,
		sig);
	CSSM_DeleteContext(sigHand);
	return crtn;
}
static int doVerify(
	CSSM_CSP_HANDLE	cspHand,
	const char *algStr,
	CSSM_KEY_PTR key,			// private
	CSSM_ALGORITHMS sigAlg,
	CSSM_RETURN expRtn,			// expected result
	CSSM_BOOL quiet)
{
	uint8 ptextData[PTEXT_SIZE];
	CSSM_DATA ptext = {PTEXT_SIZE, ptextData};
	uint8 sigData[PTEXT_SIZE];
	CSSM_DATA sig = {PTEXT_SIZE, sigData};
	
	simpleGenData(&ptext, PTEXT_SIZE, PTEXT_SIZE);
	memset(sigData, 0, PTEXT_SIZE);
	
	CSSM_CC_HANDLE cryptHand = 0;
	CSSM_RETURN crtn;
	
	crtn = CSSM_CSP_CreateSignatureContext(cspHand,
		sigAlg,
		NULL,				// passPhrase
		key,
		&cryptHand);
	if(crtn) {
		printError("CSSM_CSP_CreateSignatureContext (2)", crtn);
		return testError(quiet);
	}
	int irtn = 0;
	crtn = CSSM_VerifyData(cryptHand,
		&ptext,
		1,
		CSSM_ALGID_NONE,
		&sig);
	if(crtn != expRtn) {
		if(expRtn == CSSM_OK) {
			printError("CSSM_VerifyData", crtn);
			printf("Unexpected error verifying with %s\n", algStr);
		}
		else {
			printf("***Verify with %s: expected %s, got %s.\n",
				algStr, cssmErrToStr(expRtn),
				cssmErrToStr(crtn));
		}
		irtn = testError(quiet);
	}
	CSSM_DeleteContext(cryptHand);
	return irtn;
}
static CSSM_RETURN sigVerify(CSSM_CSP_HANDLE cspHand,
	uint32 algorithm,					// CSSM_ALGID_FEE_MD5, etc.
	CSSM_KEY_PTR key,					// public key
	const CSSM_DATA *text,
	const CSSM_DATA *sig,
	uint32 digestAlg,					// optional for raw signing
	CSSM_BOOL noPad)					// true --> add PADDING_NONE to context
{
	CSSM_CC_HANDLE	sigHand;
	CSSM_RETURN		crtn;
	
	crtn = CSSM_CSP_CreateSignatureContext(cspHand,
		algorithm,
		NULL,				// passPhrase
		key,
		&sigHand);
	if(crtn) {
		printError("CSSM_CSP_CreateSignatureContext", crtn);
		return crtn;
	}
	if(noPad) {
		crtn = AddContextAttribute(sigHand,
			CSSM_ATTRIBUTE_PADDING,
			sizeof(uint32),
			CAT_Uint32,
			NULL,
			CSSM_PADDING_NONE);
		if(crtn) {
			return crtn;
		}
	}
	crtn = CSSM_VerifyData(sigHand,
		text,
		1,
		digestAlg,
		sig);
	if(crtn) {
		printError("CSSM_VerifyData", crtn);
	}
	CSSM_DeleteContext(sigHand);
	return crtn;
}
CryptoX_Result
CryptoMac_VerifySignature(CryptoX_SignatureHandle* aInputData,
                          CryptoX_PublicKey* aPublicKey,
                          const unsigned char* aSignature,
                          unsigned int aSignatureLen)
{
  if (!aInputData || !*aInputData || !aPublicKey || !*aPublicKey ||
      !aSignature || aSignatureLen == 0) {
    return CryptoX_Error;
  }

  if (!OnLionOrLater()) {
    if (!sCspHandle) {
      return CryptoX_Error;
    }

    CSSM_KEY* publicKey;
    OSStatus status = SecKeyGetCSSMKey((SecKeyRef)*aPublicKey,
                                       (const CSSM_KEY**)&publicKey);
    if (status) {
      return CryptoX_Error;
    }

    CSSM_CC_HANDLE ccHandle;
    if (CSSM_CSP_CreateSignatureContext(sCspHandle,
                                        CSSM_ALGID_SHA1WithRSA,
                                        NULL,
                                        publicKey,
                                        &ccHandle) != CSSM_OK) {
      return CryptoX_Error;
    }

    CryptoX_Result result = CryptoX_Error;
    CSSM_DATA signatureData;
    signatureData.Data = (uint8*)aSignature;
    signatureData.Length = aSignatureLen;
    CSSM_DATA inputData;
    inputData.Data =
      CFDataGetMutableBytePtr((CFMutableDataRef)
                                (((CSSM_DATA_PTR)*aInputData)->Data));
    inputData.Length = ((CSSM_DATA_PTR)*aInputData)->Length;
    if (CSSM_VerifyData(ccHandle,
                        &inputData,
                        1,
                        CSSM_ALGID_NONE,
                        &signatureData) == CSSM_OK) {
      result = CryptoX_Success;
    }
    return result;
  }

  CFDataRef signatureData = CFDataCreate(kCFAllocatorDefault,
                                         aSignature, aSignatureLen);
  if (!signatureData) {
    return CryptoX_Error;
  }

  CFErrorRef error;
  SecTransformRef verifier =
    SecVerifyTransformCreatePtr((SecKeyRef)*aPublicKey,
                                signatureData,
                                &error);
  if (!verifier || error) {
    CFRelease(signatureData);
    return CryptoX_Error;
  }

  SecTransformSetAttributePtr(verifier,
                              kSecTransformInputAttributeName,
                              (CFDataRef)*aInputData,
                              &error);
  if (error) {
    CFRelease(signatureData);
    CFRelease(verifier);
    return CryptoX_Error;
  }

  CryptoX_Result result = CryptoX_Error;
  CFTypeRef rv = SecTransformExecutePtr(verifier, &error);
  if (error) {
    CFRelease(signatureData);
    CFRelease(verifier);
    return CryptoX_Error;
  }

  if (CFGetTypeID(rv) == CFBooleanGetTypeID() &&
      CFBooleanGetValue((CFBooleanRef)rv) == true) {
    result = CryptoX_Success;
  }

  CFRelease(signatureData);
  CFRelease(verifier);

  return result;
}
int main(int argc, char **argv)
{
	int					arg;
	char				*argp;
	unsigned			oloop;
	unsigned			iloop;
	CSSM_DATA			ptext = {0, NULL};
	CSSM_CSP_HANDLE 	cspHand;
	int					i;
	int					rtn = 0;
	uint32				keySizeInBits = 0;
	CSSM_KEY			pubKey;
	CSSM_KEY			privKey;
	CSSM_DATA			sig = {0, NULL};
	CSSM_DATA			digest = {0, NULL};
	CSSM_RETURN			crtn;
	const char			*digestStr;
	
	/*
	 * User-spec'd params
	 */
	CSSM_BOOL			keySizeSpec = CSSM_FALSE;
	unsigned			oloops = OLOOPS_DEF;
	unsigned			iloops = ILOOPS_DEF;
	CSSM_BOOL			verbose = CSSM_FALSE;
	CSSM_BOOL			quiet = CSSM_FALSE;
	unsigned			pauseInterval = 0;
	CSSM_BOOL			bareCsp = CSSM_TRUE;
	CSSM_ALGORITHMS		rawSigAlg = CSSM_ALGID_RSA;
	
	for(arg=1; arg<argc; arg++) {
		argp = argv[arg];
		switch(argp[0]) {
			case 'a':
				switch(argp[2]) {
					case 'r':
						rawSigAlg = CSSM_ALGID_RSA;
						break;
					case 'd':
						rawSigAlg = CSSM_ALGID_DSA;
						break;
					default:
						usage(argv);
				}
				break;
		    case 'l':
				oloops = atoi(&argp[2]);
				break;
		    case 'i':
				iloops = atoi(&argp[2]);
				break;
		    case 'k':
		    	keySizeInBits = atoi(&argp[2]);
				keySizeSpec = CSSM_TRUE;
				break;
		    case 'v':
		    	verbose = CSSM_TRUE;
				break;
			case 'D':
				bareCsp = CSSM_FALSE;
				break;
		    case 'q':
		    	quiet = CSSM_TRUE;
				break;
		    case 'p':
		    	pauseInterval = atoi(&argp[2]);;
				break;
		    case 'h':
		    default:
				usage(argv);
		}
	}
	
	ptext.Data = (uint8 *)CSSM_MALLOC(MAX_TEXT_SIZE);
	if(ptext.Data == NULL) {
		printf("Insufficient heap space\n");
		exit(1);
	}
	/* ptext length set in inner test loop */
	
	printf("Starting rawRsaSig; args: ");
	for(i=1; i<argc; i++) {
		printf("%s ", argv[i]);
	}
	printf("\n");
	cspHand = cspDlDbStartup(bareCsp, NULL);
	if(cspHand == 0) {
		exit(1);
	}
	if(pauseInterval) {
		fpurge(stdin);
		printf("Top of test; hit CR to proceed: ");
		getchar();
	}
	for(oloop=0; ; oloop++) {
		
		/* key size? */
		if(!keySizeSpec) {
			/* random key size */
			keySizeInBits = randKeySizeBits(rawSigAlg, OT_Sign);
		}

		if(!quiet) {
			if(verbose || ((oloop % LOOP_NOTIFY) == 0)) {
				printf("...oloop %d   keySize %u\n", oloop, (unsigned)keySizeInBits);
			}
		}
		
		/* generate a key pair */
		crtn = cspGenKeyPair(cspHand,
			rawSigAlg,
			"foo",
			3,
			keySizeInBits,
			&pubKey,
			CSSM_TRUE,						// all keys ref for speed
			CSSM_KEYUSE_VERIFY,
			CSSM_KEYBLOB_RAW_FORMAT_NONE,
			&privKey,
			CSSM_TRUE,
			CSSM_KEYUSE_SIGN,
			CSSM_KEYBLOB_RAW_FORMAT_NONE,
			CSSM_FALSE);					// genSeed not used 
		if(crtn) {
			return testError(quiet);
		}
		
		for(iloop=0; iloop<iloops; iloop++) {
		
			CSSM_ALGORITHMS		sigAlg;
			CSSM_ALGORITHMS		digestAlg;
			CSSM_CC_HANDLE		sigHand;
			
			/* alternate digest algs for RSA */
			if(rawSigAlg == CSSM_ALGID_RSA) {
				if(iloop & 1) {
					sigAlg = CSSM_ALGID_SHA1WithRSA;
					digestAlg = CSSM_ALGID_SHA1;
					digestStr = "SHA1";
				}
				else {
					sigAlg = CSSM_ALGID_MD5WithRSA;
					digestAlg = CSSM_ALGID_MD5;
					digestStr = "MD5 ";
				}
			}
			else {
				sigAlg = CSSM_ALGID_SHA1WithDSA;
				digestAlg = CSSM_ALGID_SHA1;
				digestStr = "SHA1";
			}
			
			/* new plaintext each inner loop */
			simpleGenData(&ptext, 1, MAX_TEXT_SIZE);
			if(!quiet) {
				if(verbose || ((iloop % LOOP_NOTIFY) == 0)) {
					printf("   ...iloop %d  digest %s  text size %lu\n", 
						iloop, digestStr, ptext.Length);
				}
			}
			
			/*** phase 1 ***/
			
			/* digest+sign */
			crtn = cspStagedSign(cspHand,
				sigAlg,
				&privKey,
				&ptext,
				DO_MULTI_UPDATE,			// multiUpdates
				&sig);
			if(crtn && testError(quiet)) {
				goto abort;
			}
			
			/* digest */
			crtn = cspStagedDigest(cspHand,
				digestAlg,
				CSSM_FALSE,			// mallocDigest
				DO_MULTI_UPDATE,	// multiUpdates
				&ptext, 
				&digest);
			if(crtn && testError(quiet)) {
				goto abort;
			}
			
			/* raw RSA/DSA verify */
			crtn = CSSM_CSP_CreateSignatureContext(cspHand,
				rawSigAlg,
				NULL,				// passPhrase
				&pubKey,
				&sigHand);
			if(crtn) {
				printError("CSSM_CSP_CreateSignatureContext (1)", crtn);
				return crtn;
			}
			crtn = CSSM_VerifyData(sigHand,
				&digest,
				1,
				digestAlg,
				&sig);
			if(crtn) {
				printError("CSSM_VerifyData(raw RSA)", crtn);
				if(testError(quiet)) {
					goto abort;
				}
			}
			
			/* free resources - reuse the digest for raw sign */
			appFreeCssmData(&sig, CSSM_FALSE);
			CSSM_DeleteContext(sigHand);
			
			/*** phase 2 ***/
			
			/* raw RSA/DSA sign */
			crtn = CSSM_CSP_CreateSignatureContext(cspHand,
				rawSigAlg,
				NULL,				// passPhrase
				&privKey,
				&sigHand);
			if(crtn) {
				printError("CSSM_CSP_CreateSignatureContext (1)", crtn);
				return crtn;
			}
			crtn = CSSM_SignData(sigHand,
				&digest,
				1,
				digestAlg,
				&sig);
			if(crtn) {
				printError("CSSM_SignData(raw RSA)", crtn);
				if(testError(quiet)) {
					goto abort;
				}
			}

			/* all-in-one verify */
			crtn = cspStagedSigVerify(cspHand,
				sigAlg,
				&pubKey,
				&ptext,
				&sig,
				DO_MULTI_UPDATE,		// multiUpdates
				CSSM_OK);
			if(crtn && testError(quiet)) {
				goto abort;
			}
			
			/* clean up */
			appFreeCssmData(&sig, CSSM_FALSE);
			appFreeCssmData(&digest, CSSM_FALSE);
			CSSM_DeleteContext(sigHand);
		}	/* end of inner loop */

		/* free keys */
		cspFreeKey(cspHand, &pubKey);
		cspFreeKey(cspHand, &privKey);

		if(oloops && (oloop == oloops)) {
			break;
		}
		if(pauseInterval && ((oloop % pauseInterval) == 0)) {
			fpurge(stdin);
			printf("hit CR to proceed: ");
			getchar();
		}
	}
	
abort:
	cspShutdown(cspHand, bareCsp);
	if(pauseInterval) {
		fpurge(stdin);
		printf("ModuleDetach/Unload complete; hit CR to exit: ");
		getchar();
	}
	if((rtn == 0) && !quiet) {
		printf("%s test complete\n", argv[0]);
	}
	CSSM_FREE(ptext.Data);
	return rtn;
}