Esempio n. 1
0
void EstEIDKeyHandle::generateSignature(const Context &context,
    CSSM_ALGORITHMS signOnly, const CssmData &input, CssmData &signature) {
  FLOG;
  _log("EstEIDKeyHandle::generateSignature alg: %u signOnly: %u",
  context.algorithm(), signOnly);
  IFDUMPING("esteid.tokend", context.dump("signature context"));

  if (context.type() != CSSM_ALGCLASS_SIGNATURE)
    CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);

  if (context.algorithm() != CSSM_ALGID_RSA)
    CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);

  if (signOnly == CSSM_ALGID_NONE) {
    // Special case used by SSL it's an RSA signature, without the ASN1
    // stuff
    _log("SSL signature request");
  }
  else
    CssmError::throwMe(CSSMERR_CSP_INVALID_DIGEST_ALGORITHM);
#if !defined(NDEBUG)
  context.dump("signature context");
#endif

  uint32 padding = CSSM_PADDING_PKCS1;
  context.getInt(CSSM_ATTRIBUTE_PADDING, padding);

  if (padding != CSSM_PADDING_PKCS1)
    CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);

  try {
    ByteVec result = mToken.getCard().sign(ByteVec(input.Data, input.Data + input.Length), EstEIDManager::SSL, EstEIDManager::AUTH);
    unsigned char *outputData = reinterpret_cast<unsigned char *>(malloc(result.size()));
    memcpy(outputData, &result[0], result.size());
    signature.Data = outputData;
    signature.Length = result.size();
  } catch(std::runtime_error &err) {
    _log("exception while signing");
    CssmError::throwMe(CSSMERR_CSP_FUNCTION_FAILED);
  }
}
Esempio n. 2
0
void BELPICKeyHandle::generateSignature(const Context &context,
	CSSM_ALGORITHMS signOnly, const CssmData &input, CssmData &signature)
{
	secdebug("crypto", "generateSignature alg: %u signOnly: %u",
		context.algorithm(), signOnly);
	IFDUMPING("crypto", context.dump("signature context"));

	if (context.type() != CSSM_ALGCLASS_SIGNATURE)
		CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);

	if (context.algorithm() != CSSM_ALGID_RSA)
		CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);

	// Find out if we are doing a SHA1 or MD5 signature and setup header to
	// point to the right asn1 blob.
	const unsigned char *header;
	size_t headerLength;
	if (signOnly == CSSM_ALGID_SHA1)
	{
		if (input.Length != 20)
			CssmError::throwMe(CSSMERR_CSP_BLOCK_SIZE_MISMATCH);

		header = sha1sigheader;
		headerLength = sizeof(sha1sigheader);
	}
	else if (signOnly == CSSM_ALGID_MD5)
	{
		if (input.Length != 16)
			CssmError::throwMe(CSSMERR_CSP_BLOCK_SIZE_MISMATCH);

		header = md5sigheader;
		headerLength = sizeof(md5sigheader);
	}
	else if (signOnly == CSSM_ALGID_NONE)
	{
		// Special case used by SSL it's an RSA signature, without the ASN1
		// stuff
		header = NULL;
		headerLength = 0;

		// @@@ Fix me
		//CssmError::throwMe(CSSMERR_CSP_BLOCK_SIZE_MISMATCH);
	}
	else
		CssmError::throwMe(CSSMERR_CSP_INVALID_DIGEST_ALGORITHM);

#if 0
	// @@@ Hack for BELPIC card!
	header = NULL;
	headerLength = 0;
#endif

	// Create an input buffer in which we construct the data we will send to
	// the token.
	size_t inputDataSize = headerLength + input.Length;
	size_t keyLength = mKey.sizeInBits() / 8;
	auto_array<unsigned char> inputData(keyLength);
	unsigned char *to = inputData.get();

	// Get padding, but default to pkcs1 style padding
	uint32 padding = CSSM_PADDING_PKCS1;
	context.getInt(CSSM_ATTRIBUTE_PADDING, padding);

#if 1
	if (padding != CSSM_PADDING_PKCS1)
		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
#else
	if (padding == CSSM_PADDING_PKCS1)
	{
		// Add PKCS1 style padding
		*(to++) = 0;
		*(to++) = 1; /* Private Key Block Type. */
		size_t padLength = keyLength - 3 - inputDataSize;
		memset(to, 0xff, padLength);
		to += padLength;
		*(to++) = 0;
		inputDataSize = keyLength;
	}
	else if (padding == CSSM_PADDING_NONE)
	{
		// Token will fail if the input data isn't exactly keysize / 8 octects
		// long
	}
	else
		CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
#endif

	// Now copy the ASN1 header into the input buffer.
	// This header is the DER encoding of
	// DigestInfo ::= SEQUENCE { digestAlgorithm AlgorithmIdentifier,
	// digest OCTET STRING }
	// Where AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER,
	// parameters OPTIONAL ANY }
	if (headerLength)
	{
		memcpy(to, header, headerLength);
		to += headerLength;
	}

	// Finally copy the passed in data to the input buffer.
	memcpy(to, input.Data, input.Length);

	// @@@ Switch to using tokend allocators
	unsigned char *outputData =
		reinterpret_cast<unsigned char *>(malloc(keyLength));
	size_t outputLength = keyLength;
	try
	{
		const AccessCredentials *cred = context.get<const AccessCredentials>(
			CSSM_ATTRIBUTE_ACCESS_CREDENTIALS);
		// Sign the inputData using the token
		mKey.computeCrypt(mToken, true, cred, inputData.get(), inputDataSize,
			outputData, outputLength);
	}
	catch (...)
	{
		// @@@ Switch to using tokend allocators
		free(outputData);
		throw;
	}

	signature.Data = outputData;
	signature.Length = outputLength;
}