Exemplo n.º 1
0
/** Return a string with the printed digest of the given key file,
    or NULL if an error occurred. */
char* GetPubkeyDigest(const char* pubkey)
{
    unsigned char digest[EVP_MAX_MD_SIZE + 1];
    RSA* key = NULL;
    char* buffer = xmalloc(EVP_MAX_MD_SIZE * 4);

    key = LoadPublicKey(pubkey);
    if (NULL == key)
    {
        return NULL;
    }

    HashPubKey(key, digest, CF_DEFAULT_DIGEST);
    HashPrintSafe(CF_DEFAULT_DIGEST, digest, buffer);
    return buffer;
}
Exemplo n.º 2
0
	/// <summary>
	/// Authenticates cartridge by verifying its certificate and its signature of a random token.
	/// </summary>
	/// <param name="ucCartridgeNum">The cartridge number.</param>
	/// <param name="aucPubKS">Stratasys public key.</param>
	/// <param name="aucIdd">The tag identification data (output parameter).</param>
	/// <param name="usIddLength">The tag identification data length (output parameter).</param>
	/// <param name="uiCurrentVolume">The tag current volume (output parameter).</param>
	/// <returns>0 on success, non-zero for failures.</returns>
	int MaterialMonitor::AuthenticateCartridge(unsigned char ucCartridgeNum, const unsigned char *aucPubKS, unsigned char *aucIdd, unsigned short *usIddLength, unsigned int *uiCurrentVolume)
	{
		UniqueLock uniqueLock(m_mtx);

		int returnValue = IDTLIB_SUCCESS;
		if (aucPubKS == NULL && m_pubKS == NULL)
		{
			returnValue = INVALID_HOST_KEY;
			LOG_EXT(LEVEL_ERROR, "Invalid host key (error code 0x" << hex << (short)returnValue << ").");
			return returnValue;
		}

		if (aucIdd == NULL || usIddLength == NULL || uiCurrentVolume == NULL)
		{
			returnValue = AUTHENTICATE_NULL_PARAMS;
			LOG_EXT(LEVEL_ERROR, "Invalid parameters (error code 0x" << hex << (short)returnValue << ").");
			return returnValue;
		}

		if (!m_bInitialized)
		{
			returnValue = HW_NOT_INITIALIZED;
			LOG_EXT(LEVEL_ERROR, "Hardware not initialized (error code 0x" << hex << (short)returnValue << ").");
			return returnValue;
		}

		try
		{
			LOG_EXT(LEVEL_INFO, "Cartridge #" << (unsigned short)ucCartridgeNum << " authentication started:");
			LOG_EXT(LEVEL_INFO, "Reset cartridge #"<< (unsigned short)ucCartridgeNum << " info...");
			int returnValue = ResetCartridgeInfo(ucCartridgeNum);
			if (returnValue != IDTLIB_SUCCESS)
			{
				LOG_EXT(LEVEL_ERROR, "Error resetting cartridge #"<< (unsigned short)ucCartridgeNum << " info (number of cartridges: " << (unsigned short)m_ucCartridgesCount << ", error code 0x" << hex << (short)returnValue << ").");
				return returnValue;
			}

			LOG_EXT(LEVEL_INFO, "Switching to cartridge #"<< (unsigned short)ucCartridgeNum << "...");
			returnValue = m_tagAdapter->SwitchToCartridge(ucCartridgeNum);
			if (returnValue != IDTLIB_SUCCESS)
			{
				LOG_EXT(LEVEL_ERROR, "Error switching to cartridge #"<< (unsigned short)ucCartridgeNum << " (number of cartridges: " << (unsigned short)m_ucCartridgesCount << ", error code 0x" << hex << (short)returnValue << ").");
				return returnValue;
			}

			LOG_EXT(LEVEL_INFO, "Reading ID certificate...");
			unsigned char aucBuffer[CERTIFICATE_SIZE];
			memset(aucBuffer, 0, sizeof(aucBuffer));
			returnValue = ReadIDCertificate(aucBuffer);
			if (returnValue != IDTLIB_SUCCESS)
			{
				LOG_EXT(LEVEL_ERROR, "Error reading ID certificate (error code 0x" << hex << (short)returnValue << ").");
				return returnValue;
			}

			bool isEmpty = m_tagAdapter->IsCertificateEmpty(aucBuffer);
			if (isEmpty)
			{
				returnValue = EMPTY_CERTIFICATE_FILE;
				LOG_EXT(LEVEL_ERROR, "Tag is blank (error code 0x" << hex << (short)returnValue << ").");
				return returnValue;
			}

			LOG_EXT(LEVEL_DEBUG, "Extracting cartridge #" << (unsigned short)ucCartridgeNum << " public key...");
			IDCertificate *certificate = new IDCertificate();
			unsigned short certificateSize;
			try
			{
				certificateSize = (unsigned short)certificate->Decode(aucBuffer);
			}
			catch (exception& e)
			{
				delete certificate;
				returnValue = INVALID_CERTIFICATE_FILE;
				LOG_EXT(LEVEL_ERROR, "Invalid certificate (error code 0x" << hex << (short)returnValue << "): " << e.what() << ".");
				return returnValue;
			}

			*usIddLength = certificateSize - SIGNATURE_SIZE - PUBLIC_KEY_SIZE;
			memcpy(aucIdd, aucBuffer, *usIddLength);

			ECDSA<EC2N, SHA256>::PublicKey* pubKS;
			if (aucPubKS != NULL)
			{
				pubKS = LoadPublicKey(aucPubKS);
				if (pubKS == NULL)
				{
					delete certificate;
					return INVALID_HOST_KEY;
				}
			}
			else
			{
				pubKS = m_pubKS;
			}

			LOG_EXT(LEVEL_INFO, "Verifying ID certificate...");
			SetVerifier(pubKS);
			pthread_t verifierThread;
			VerifyParameters* verifyParameters = CreateVerifyParameters(
				m_veriferS,
				aucBuffer,
				certificateSize - SIGNATURE_SIZE,
				aucBuffer + (certificateSize - SIGNATURE_SIZE),
				SIGNATURE_SIZE);
			CreateVerifierThread(&verifierThread, verifyParameters);

			LOG_EXT(LEVEL_INFO, "Sending random token for IDT to sign...");
			byte aucHostChallenge[TOKEN_SIZE];
			GenerateToken(aucHostChallenge, TOKEN_SIZE);

			byte aucDeviceChallenge[64]; // expected device challenge length
			byte aucSignedDeviceChallenge[SIGNATURE_SIZE];
			unsigned short usDeviceChallengeLength = sizeof(aucDeviceChallenge);
			unsigned short usSignedDeviceChallengeLength = sizeof(aucSignedDeviceChallenge);
			returnValue = ChallengeHostDevice(ucCartridgeNum, aucHostChallenge, TOKEN_SIZE, aucDeviceChallenge, &usDeviceChallengeLength, aucSignedDeviceChallenge, &usSignedDeviceChallengeLength);

			void* status;
			pthread_join(verifierThread, &status);
			delete verifyParameters;
			if (!m_bVerified)
			{
				returnValue = INVALID_CERTIFICATE_SIGNATURE;
				LOG_EXT(LEVEL_ERROR, "Error verifying ID certificate (error code 0x" << hex << (short)returnValue << ").");
				delete certificate;
				return returnValue;
			}

			if (returnValue != IDTLIB_SUCCESS)
			{
				LOG_EXT(LEVEL_ERROR, "Error sending random token to IDT (error code 0x" << hex << (short)returnValue << ").");
				delete certificate;
				return returnValue;
			}

			LOG_EXT(LEVEL_INFO, "Verifying IDT signature...");
			verifyParameters = CreateVerifyParameters(
				certificate->IDD.GetVerifier(),
				aucDeviceChallenge,
				usDeviceChallengeLength,
				aucSignedDeviceChallenge,
				usSignedDeviceChallengeLength);
			CreateVerifierThread(&verifierThread, verifyParameters);

			LOG_EXT(LEVEL_INFO, "Getting current volume...");
			returnValue = GetCurrentVolume(ucCartridgeNum, uiCurrentVolume);

			pthread_join(verifierThread, &status);
			delete verifyParameters;
			if (!m_bVerified)
			{
				returnValue = INVALID_TOKEN_SIGNATURE;
				LOG_EXT(LEVEL_ERROR, "Invalid signature (error code 0x" << hex << (short)returnValue << ").");
				delete certificate;
				return returnValue;
			}

			if (returnValue != IDTLIB_SUCCESS)
			{
				LOG_EXT(LEVEL_ERROR, "Error getting current volume (error code 0x" << hex << (short)returnValue << ").");
				delete certificate;
				return returnValue;
			}

			m_certificates[ucCartridgeNum] = certificate;
			LOG_EXT(LEVEL_INFO, "Cartridge #" << (unsigned short)ucCartridgeNum << " authentication ended successfully. Current weight: " << *uiCurrentVolume << " milligrams.");
			return returnValue;
		}
		catch (exception& e)
		{
			LOG_EXT(LEVEL_ERROR, "Exception caught: " << e.what() << ".");
			return EXCEPTION_CAUGHT;
		}
	}
Exemplo n.º 3
0
	///
	/// Authenticates cartridge.
	///
	int MaterialMonitorSim::AuthenticateCartridge(unsigned char ucCartridgeNum, const unsigned char *aucPubKS, unsigned char *aucIdd, unsigned short *usIddLength, unsigned int *uiCurrentVolume)
	{
		UniqueLock uniqueLock(m_mtx);

		int returnValue = IDTLIB_SUCCESS;
		if (aucPubKS == NULL && m_pubKS == NULL)
		{
			returnValue = INVALID_HOST_KEY;
			LOG_EXT(LEVEL_ERROR, "Invalid host key (error code 0x" << hex << (short)returnValue << ").");
			return returnValue;
		}

		if (aucIdd == NULL || usIddLength == NULL || uiCurrentVolume == NULL)
		{
			returnValue = AUTHENTICATE_NULL_PARAMS;
			LOG_EXT(LEVEL_ERROR, "Invalid parameters (error code 0x" << hex << (short)returnValue << ").");
			return returnValue;
		}

		if (!m_bInitialized)
		{
			returnValue = HW_NOT_INITIALIZED;
			LOG_EXT(LEVEL_ERROR, "Hardware not initialized (error code 0x" << hex << (short)returnValue << ").");
			return returnValue;
		}

		try
		{
			int behaviorReturnValue = GetAuthenticateCartridgeBehavior(ucCartridgeNum, aucPubKS, aucIdd, usIddLength, uiCurrentVolume);

			LOG_EXT(LEVEL_INFO, "Cartridge #" << (unsigned short)ucCartridgeNum << " authentication started:");
			LOG_EXT(LEVEL_INFO, "Switching to cartridge #"<< (unsigned short)ucCartridgeNum << "...");
			if (((m_behavior != NULL) && !IsCartridgeOn(ucCartridgeNum, m_behavior->Status)) ||
				behaviorReturnValue == FCB_SELECT_CHANNEL_FAILED)
			{
				returnValue = FCB_SELECT_CHANNEL_FAILED;
				LOG_EXT(LEVEL_ERROR, "Error switching to cartridge #"<< (unsigned short)ucCartridgeNum << " (error code 0x" << hex << (short)returnValue << ").");
				return returnValue;
			}

			ResetCartridgeInfo(ucCartridgeNum);

			// read certificate file
			LOG_EXT(LEVEL_INFO, "Getting ID certificate...");
			string sCertificateFileName = GetCartridgeFileName(ucCartridgeNum, CERTIFICATE_FILE);

			FILE *pCertificateFile = fopen(sCertificateFileName.c_str(), "rb");
			if (pCertificateFile == NULL || behaviorReturnValue == INVALID_CERTIFICATE_FILE)
			{
				returnValue = INVALID_CERTIFICATE_FILE;
				LOG_EXT(LEVEL_ERROR, "Error getting ID certificate (error code 0x" << hex << (short)returnValue << ").");
				return returnValue;
			}

			fseek(pCertificateFile , 0 , SEEK_END);
			size_t fileSize = (size_t)ftell(pCertificateFile);
			rewind(pCertificateFile);
			fread(aucIdd, sizeof(unsigned char), fileSize, pCertificateFile);

			IDCertificate idc;
			*usIddLength = (unsigned short)idc.Decode(aucIdd) - SIGNATURE_SIZE;

			ECDSA<EC2N, SHA256>::PublicKey* pubKS;
			if (aucPubKS != NULL)
			{
				pubKS = LoadPublicKey(aucPubKS);
				if (pubKS == NULL)
				{
					return INVALID_HOST_KEY;
				}
			}
			else
			{
				pubKS = m_pubKS;
			}

			if (returnValue == INVALID_HOST_KEY || behaviorReturnValue == INVALID_HOST_KEY)
			{
				returnValue = INVALID_HOST_KEY;
				LOG_EXT(LEVEL_ERROR, "Invalid host key (error code 0x" << hex << (short)returnValue << ").");
				return returnValue;
			}

			// verify signature:
			ECDSA<EC2N, SHA256>::Verifier verifier(*pubKS);
			bool ok;
			try
			{
				ok = verifier.VerifyMessage(aucIdd, *usIddLength, aucIdd + *usIddLength, SIGNATURE_SIZE);
			}
			catch (exception& e)
			{
				LOG_EXT(LEVEL_ERROR, "Error verifying ID certificate (error code 0x" << hex << (short)returnValue << "):" << e.what() << ".");
				ok = false;
			}

			if (!ok || behaviorReturnValue == INVALID_CERTIFICATE_SIGNATURE)
			{
				returnValue = INVALID_CERTIFICATE_SIGNATURE;
				LOG_EXT(LEVEL_ERROR, "Error verifying ID certificate (error code 0x" << hex << (short)returnValue << ").");
				return returnValue;
			}

			// read counter
			returnValue = ReadCounter(ucCartridgeNum, uiCurrentVolume);
			if (returnValue != IDTLIB_SUCCESS)
			{
				if (returnValue == INVALID_VOLUME_SIGNATURE || behaviorReturnValue == INVALID_VOLUME_SIGNATURE)
				{
					LOG_EXT(LEVEL_ERROR, "Error verifying signature (error code 0x" << hex << (short)returnValue << ").");
				}
				else
				{
					LOG_EXT(LEVEL_ERROR, "Error reading counter (error code 0x" << hex << (short)returnValue << ").");
				}

				return returnValue;
			}

			returnValue = behaviorReturnValue;
			if (returnValue == IDTLIB_SUCCESS)
			{
				m_authenticated |= (1 << ucCartridgeNum);
				LOG_EXT(LEVEL_INFO, "Cartridge #" << (unsigned short)ucCartridgeNum << " authentication ended successfully. Current volume: " << *uiCurrentVolume << ".");
			}
			else
			{
				LOG_EXT(LEVEL_ERROR, "Error authenticating cartridge (error code 0x" << hex << (short)returnValue << ").");
			}

			return returnValue;
		}
		catch (exception& e)
		{
			LOG_EXT(LEVEL_ERROR, "Exception caught: " << e.what() << ".");
			return EXCEPTION_CAUGHT;
		}
	}