/*============================================================================ * OpcUa_P_OpenSSL_RSA_LoadPrivateKeyFromFile *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_RSA_LoadPrivateKeyFromFile( OpcUa_StringA a_privateKeyFile, OpcUa_P_FileFormat a_fileFormat, OpcUa_StringA a_password, /* optional: just needed encrypted PEM */ OpcUa_ByteString* a_pPrivateKey) { BIO* pPrivateKeyFile = OpcUa_Null; RSA* pRsaPrivateKey = OpcUa_Null; EVP_PKEY* pEvpKey = OpcUa_Null; unsigned char* pData; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "RSA_LoadPrivateKeyFromFile"); /* check parameters */ OpcUa_ReturnErrorIfArgumentNull(a_privateKeyFile); OpcUa_ReturnErrorIfArgumentNull(a_pPrivateKey); if(a_fileFormat == OpcUa_Crypto_Encoding_Invalid) { return OpcUa_BadInvalidArgument; } OpcUa_ReferenceParameter(a_password); /* open file */ pPrivateKeyFile = BIO_new_file((const char*)a_privateKeyFile, "rb"); OpcUa_ReturnErrorIfArgumentNull(pPrivateKeyFile); /* read and convert file */ switch(a_fileFormat) { case OpcUa_Crypto_Encoding_PEM: { /* read from file */ pEvpKey = PEM_read_bio_PrivateKey( pPrivateKeyFile, /* file */ NULL, /* key struct */ 0, /* password callback */ a_password); /* default passphrase or arbitrary handle */ OpcUa_GotoErrorIfNull(pEvpKey, OpcUa_Bad); break; } case OpcUa_Crypto_Encoding_PKCS12: { int iResult = 0; /* read from file. */ PKCS12* pPkcs12 = d2i_PKCS12_bio(pPrivateKeyFile, NULL); if (pPkcs12 == 0) { OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError); } /* parse the certificate. */ iResult = PKCS12_parse(pPkcs12, a_password, &pEvpKey, NULL, NULL); if (iResult == 0) { OpcUa_GotoErrorWithStatus(OpcUa_BadEncodingError); } /* free certificate. */ PKCS12_free(pPkcs12); pPkcs12 = NULL; break; } case OpcUa_Crypto_Encoding_DER: default: { uStatus = OpcUa_BadNotSupported; OpcUa_GotoError; } } /* convert to intermediary openssl struct */ pRsaPrivateKey = EVP_PKEY_get1_RSA(pEvpKey); EVP_PKEY_free(pEvpKey); OpcUa_GotoErrorIfNull(pRsaPrivateKey, OpcUa_Bad); /* get required length */ a_pPrivateKey->Length = i2d_RSAPrivateKey(pRsaPrivateKey, OpcUa_Null); OpcUa_GotoErrorIfTrue((a_pPrivateKey->Length <= 0), OpcUa_Bad); /* allocate target buffer */ a_pPrivateKey->Data = (OpcUa_Byte*)OpcUa_P_Memory_Alloc(a_pPrivateKey->Length); OpcUa_GotoErrorIfAllocFailed(a_pPrivateKey->Data); /* do real conversion */ pData = a_pPrivateKey->Data; a_pPrivateKey->Length = i2d_RSAPrivateKey(pRsaPrivateKey, &pData); OpcUa_GotoErrorIfTrue((a_pPrivateKey->Length <= 0), OpcUa_Bad); RSA_free(pRsaPrivateKey); BIO_free(pPrivateKeyFile); OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pEvpKey) { EVP_PKEY_free(pEvpKey); } if(a_pPrivateKey != OpcUa_Null) { if(a_pPrivateKey->Data != OpcUa_Null) { OpcUa_P_Memory_Free(a_pPrivateKey->Data); a_pPrivateKey->Data = OpcUa_Null; a_pPrivateKey->Length = -1; } } if(pPrivateKeyFile != NULL) { BIO_free(pPrivateKeyFile); } if(pRsaPrivateKey != NULL) { RSA_free(pRsaPrivateKey); } OpcUa_FinishErrorHandling; }
/*============================================================================ * OpcUa_P_OpenSSL_X509_GetPrivateKey *===========================================================================*/ OpcUa_StatusCode OpcUa_P_OpenSSL_X509_GetPrivateKey( OpcUa_CryptoProvider* a_pProvider, OpcUa_StringA a_certificateFileName, OpcUa_StringA a_password, /* this is optional */ OpcUa_Key* a_pPrivateKey) { BIO* pCertFile = OpcUa_Null; PKCS12* pPKCS12Cert = OpcUa_Null; EVP_PKEY* pPrivateKey = OpcUa_Null; RSA* pRsaPrivateKey = OpcUa_Null; OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_GetPrivateKey"); OpcUa_ReferenceParameter(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_pProvider); OpcUa_ReturnErrorIfArgumentNull(a_certificateFileName); OpcUa_ReturnErrorIfArgumentNull(a_pPrivateKey); /* import certificate from file by the given encoding type */ pCertFile = BIO_new_file((const char*)a_certificateFileName, "r"); OpcUa_ReturnErrorIfArgumentNull(pCertFile); /* convert certificate file handle to PKCS12 structure */ d2i_PKCS12_bio(pCertFile, &pPKCS12Cert); /* close certificat file handle */ BIO_free(pCertFile); if(pPKCS12Cert != OpcUa_Null) { /* get the private key from the PKCS12 structure*/ PKCS12_parse(pPKCS12Cert, a_password, &pPrivateKey, OpcUa_Null, OpcUa_Null); } else { uStatus = OpcUa_Bad; OpcUa_ReturnStatusCode; } if(pPKCS12Cert != OpcUa_Null) { PKCS12_free(pPKCS12Cert); pPKCS12Cert = OpcUa_Null; } switch(EVP_PKEY_type(pPrivateKey->type)) { case EVP_PKEY_RSA: { /* convert to intermediary openssl struct */ pRsaPrivateKey = EVP_PKEY_get1_RSA(pPrivateKey); EVP_PKEY_free(pPrivateKey); OpcUa_GotoErrorIfNull(pRsaPrivateKey, OpcUa_Bad); /* get required length */ a_pPrivateKey->Key.Length = i2d_RSAPrivateKey(pRsaPrivateKey, OpcUa_Null); OpcUa_GotoErrorIfTrue(a_pPrivateKey->Key.Length <= 0, OpcUa_Bad); if(a_pPrivateKey->Key.Data == OpcUa_Null) { OpcUa_ReturnStatusCode; } /* do real conversion */ a_pPrivateKey->Key.Length = i2d_RSAPrivateKey( pRsaPrivateKey, &a_pPrivateKey->Key.Data); OpcUa_GotoErrorIfTrue(a_pPrivateKey->Key.Length <= 0, OpcUa_Bad); if(pRsaPrivateKey != OpcUa_Null) { RSA_free(pRsaPrivateKey); pRsaPrivateKey = OpcUa_Null; } /* correct buffer pointer */ a_pPrivateKey->Key.Data -= a_pPrivateKey->Key.Length; a_pPrivateKey->Type = OpcUa_Crypto_KeyType_Rsa_Private; break; } case EVP_PKEY_EC: case EVP_PKEY_DSA: case EVP_PKEY_DH: default: { uStatus = OpcUa_BadNotSupported; OpcUa_GotoErrorIfBad(uStatus); } } OpcUa_ReturnStatusCode; OpcUa_BeginErrorHandling; if(pRsaPrivateKey != OpcUa_Null) { RSA_free(pRsaPrivateKey); } if(pPrivateKey != OpcUa_Null) { EVP_PKEY_free(pPrivateKey); } OpcUa_FinishErrorHandling; }