HRESULT Library_spot_net_security_native_Microsoft_SPOT_Net_Security_SslNative::InitHelper( CLR_RT_StackFrame& stack, bool isServer ) { NATIVE_PROFILE_CLR_NETWORK(); TINYCLR_HEADER(); CLR_INT32 sslContext = -1; CLR_INT32 sslMode = stack.Arg0().NumericByRef().s4; CLR_INT32 sslVerify = stack.Arg1().NumericByRef().s4; CLR_RT_HeapBlock *hbCert = stack.Arg2().Dereference(); CLR_RT_HeapBlock_Array* arrCA = stack.Arg3().DereferenceArray(); CLR_RT_HeapBlock_Array* arrCert = NULL; CLR_UINT8* sslCert = NULL; int result; int i; bool isFirstCall = false; LPCSTR szPwd = ""; if(!g_SSL_SeedData.Initialized) { BOOL fOK = FALSE; isFirstCall = true; #if !defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) int i; if(!HAL_CONFIG_BLOCK::ApplyConfig( g_SSL_SeedData.Config.GetDriverName(), &g_SSL_SeedData.Config, sizeof(g_SSL_SeedData.Config) )) { return CLR_E_NOT_SUPPORTED; } // validate the security key (make sure it isn't all 0x00 or all 0xFF for(i=1; i<sizeof(g_SSL_SeedData.Config.SslSeedKey) && !fOK; i++) { if( g_SSL_SeedData.Config.SslSeedKey[ i ] != 0 && g_SSL_SeedData.Config.SslSeedKey[ i ] != 0xFF && g_SSL_SeedData.Config.SslSeedKey[ i-1 ] != g_SSL_SeedData.Config.SslSeedKey[ i ]) { fOK = TRUE; } } if(!fOK) { return CLR_E_NOT_SUPPORTED; } #endif g_SSL_SeedData.m_completion.Initialize(); g_SSL_SeedData.m_completion.InitializeForUserMode( UpdateSslSeedValue, NULL ); g_SSL_SeedData.Initialized = TRUE; } if(hbCert != NULL) { arrCert = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_certificate ].DereferenceArray(); //FAULT_ON_NULL(arrCert); // If arrCert == NULL then the certificate is an X509Certificate2 which uses a certificate handle if(arrCert == NULL) { arrCert = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_handle ].DereferenceArray(); FAULT_ON_NULL(arrCert); // pass the certificate handle as the cert data parameter sslCert = arrCert->GetFirstElement(); arrCert = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_sessionHandle ].DereferenceArray(); FAULT_ON_NULL(arrCert); // pass the session handle as the ssl context parameter sslContext = *(INT32*)arrCert->GetFirstElement(); // the certificate has already been loaded so just pass an empty string szPwd = ""; } else { arrCert->Pin(); sslCert = arrCert->GetFirstElement(); CLR_RT_HeapBlock *hbPwd = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_password ].Dereference();// FAULT_ON_NULL(hbPwd); szPwd = hbPwd->StringText(); } } SSL_RegisterTimeCallback( Time_GetDateTime ); if(isServer) { result = (SSL_ServerInit( sslMode, sslVerify, (const char*)sslCert, sslCert == NULL ? 0 : arrCert->m_numOfElements, szPwd, sslContext ) ? 0 : -1); } else { result = (SSL_ClientInit( sslMode, sslVerify, (const char*)sslCert, sslCert == NULL ? 0 : arrCert->m_numOfElements, szPwd, sslContext ) ? 0 : -1); } TINYCLR_CHECK_HRESULT(ThrowOnError( stack, result )); if(isFirstCall) { GenerateNewSslSeed(); } if(arrCA != NULL) { for(i=0; i<(int)arrCA->m_numOfElements; i++) { hbCert = (CLR_RT_HeapBlock*)arrCA->GetElement( i ); FAULT_ON_NULL(hbCert); hbCert = hbCert->Dereference(); FAULT_ON_NULL(hbCert); arrCert = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_certificate ].DereferenceArray(); //FAULT_ON_NULL(arrCert); // If arrCert == NULL then the certificate is an X509Certificate2 which uses a certificate handle if(arrCert == NULL) { CLR_INT32 sessionCtx = 0; arrCert = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_handle ].DereferenceArray(); FAULT_ON_NULL(arrCert); sslCert = arrCert->GetFirstElement(); arrCert = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_sessionHandle ].DereferenceArray(); FAULT_ON_NULL(arrCert); sessionCtx = *(INT32*)arrCert->GetFirstElement(); // pass the session handle down as the password paramter and the certificate handle as the data parameter result = (SSL_AddCertificateAuthority( sslContext, (const char*)sslCert, arrCert->m_numOfElements, (LPCSTR)&sessionCtx ) ? 0 : -1); TINYCLR_CHECK_HRESULT(ThrowOnError( stack, result )); } else { arrCert->Pin(); sslCert = arrCert->GetFirstElement(); CLR_RT_HeapBlock *hbPwd = hbCert[ Library_spot_native_System_Security_Cryptography_X509Certificates_X509Certificate::FIELD__m_password ].Dereference(); FAULT_ON_NULL(hbPwd); LPCSTR szCAPwd = hbPwd->StringText(); result = (SSL_AddCertificateAuthority( sslContext, (const char*)sslCert, arrCert->m_numOfElements, szCAPwd ) ? 0 : -1); TINYCLR_CHECK_HRESULT(ThrowOnError( stack, result )); } } } stack.SetResult_I4( sslContext ); TINYCLR_CLEANUP(); if(FAILED(hr) && (sslContext != -1)) { SSL_ExitContext( sslContext ); } TINYCLR_CLEANUP_END(); }