//MS: populate DATE_TIME_INFO struct with year,month, day,hour,minute,second,etc static int ssl_get_ASN1_UTCTIME(const ASN1_UTCTIME *tm, DATE_TIME_INFO *dti) { const char *v; int gmt=0; int i; int y=0,M=0,d=0,h=0,m=0,s=0; memset(dti, 0, sizeof(*dti)); i=tm->length; v=(const char *)tm->data; if (i < 10) { goto err; } if (v[i-1] == 'Z') gmt=1; for (i=0; i<10; i++) if ((v[i] > '9') || (v[i] < '0')) { goto err; } y= (v[0]-'0')*10+(v[1]-'0'); if (y < 50) y+=100; M= (v[2]-'0')*10+(v[3]-'0'); if ((M > 12) || (M < 1)) { goto err; } d= (v[4]-'0')*10+(v[5]-'0'); h= (v[6]-'0')*10+(v[7]-'0'); m= (v[8]-'0')*10+(v[9]-'0'); if (tm->length >=12 && (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9')) s= (v[10]-'0')*10+(v[11]-'0'); dti->year = SwapEndianIfBEc32(y+1900); dti->month = SwapEndianIfBEc32(M); dti->day = SwapEndianIfBEc32(d); dti->hour = SwapEndianIfBEc32(h); dti->minute = SwapEndianIfBEc32(m); dti->second = SwapEndianIfBEc32(s); dti->dlsTime = 0; //TODO:HOW to find dti->tzOffset = SwapEndianIfBEc32(gmt); //TODO:How to find return(1); err: TINYCLR_SSL_PRINTF("Bad time value\r\n"); return(0); }
CK_RV PKCS11_Objects_OpenSSL::FindObjectsInit(Cryptoki_Session_Context* pSessionCtx, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { FIND_OBJECT_DATA *pData; INT32 i = 0, len; if(pSessionCtx->FindObjectsCtx != NULL) { return CKR_FUNCTION_NOT_PARALLEL; } pData = (FIND_OBJECT_DATA*)TINYCLR_SSL_MALLOC(sizeof(FIND_OBJECT_DATA)); if(pData == NULL) return CKR_DEVICE_MEMORY; pSessionCtx->FindObjectsCtx = pData; pData->FileName[0] = 0; pData->GroupName[0] = 0; while(i < ulCount) { switch(pTemplate[i].type) { case CKA_CLASS: switch(SwapEndianIfBEc32(*(INT32*)pTemplate[i].pValue)) { case CKO_CERTIFICATE: pData->ObjectType = CertificateType; break; case CKO_PUBLIC_KEY: case CKO_SECRET_KEY: case CKO_PRIVATE_KEY: pData->ObjectType = KeyType; break; default: pData->ObjectType = DataType; break; } break; case CKA_LABEL: len = pTemplate[i].ulValueLen; if(len >= ARRAYSIZE(pData->GroupName)) { len = ARRAYSIZE(pData->GroupName) - 1; } TINYCLR_SSL_MEMCPY( pData->GroupName, pTemplate[i].pValue, len ); pData->GroupName[len] = 0; break; case CKA_OBJECT_ID: len = pTemplate[i].ulValueLen; if(len >= ARRAYSIZE(pData->FileName)) { len = ARRAYSIZE(pData->FileName) - 1; } TINYCLR_SSL_MEMCPY( pData->FileName, pTemplate[i].pValue, len ); pData->FileName[len] = 0; break; default: return CKR_ATTRIBUTE_TYPE_INVALID; } i++; } return CKR_OK; }
CK_RV PKCS11_Objects_OpenSSL::SetAttributeValue(Cryptoki_Session_Context* pSessionCtx, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { OBJECT_DATA* pObj = PKCS11_Objects_OpenSSL::GetObjectFromHandle(pSessionCtx, hObject); if(pObj == NULL) return CKR_OBJECT_HANDLE_INVALID; if(pObj->Type == CertificateType) { CERT_DATA* pCertData = (CERT_DATA*)pObj->Data; X509* pCert = pCertData->cert; CHAR group[20] = {0}; CHAR fileName[20] = {0}; INT32 len = 0; BOOL fSave = FALSE; BOOL fDelete = FALSE; for(int i=0; i<(int)ulCount; i++) { switch(pTemplate[i].type) { case CKA_PERSIST: fSave = SwapEndianIfBEc32(*(INT32*)pTemplate[i].pValue) != 0; fDelete = !fSave; break; case CKA_LABEL: len = pTemplate[i].ulValueLen; if(len >= ARRAYSIZE(group)) { len = ARRAYSIZE(group) - 1; } TINYCLR_SSL_MEMCPY(group, pTemplate[i].pValue, len); group[len] = 0; break; case CKA_OBJECT_ID: len = pTemplate[i].ulValueLen; if(len >= ARRAYSIZE(fileName)) { len = ARRAYSIZE(fileName) - 1; } TINYCLR_SSL_MEMCPY(fileName, pTemplate[i].pValue, len); fileName[len] = 0; break; default: return CKR_ATTRIBUTE_TYPE_INVALID; } } if(fDelete) { hal_strcpy_s(fileName, ARRAYSIZE(pObj->FileName), pObj->FileName); pObj->GroupName[0] = 0; if(g_OpenSSL_Token.Storage != NULL && g_OpenSSL_Token.Storage->Delete != NULL) { if(!g_OpenSSL_Token.Storage->Delete(fileName, group)) return CKR_FUNCTION_FAILED; } else { return CKR_FUNCTION_NOT_SUPPORTED; } } else if(fSave) { hal_strcpy_s(pObj->GroupName, ARRAYSIZE(pObj->GroupName), group ); hal_strcpy_s(pObj->FileName , ARRAYSIZE(pObj->FileName ), fileName); if(g_OpenSSL_Token.Storage != NULL && g_OpenSSL_Token.Storage->Create != NULL) { BOOL res; UINT8* pData, *pTmp; INT32 len = i2d_X509( pCert, NULL ); if(len <= 0) return CKR_FUNCTION_FAILED; pData = (UINT8*)TINYCLR_SSL_MALLOC(len); if(pData == NULL) return CKR_DEVICE_MEMORY; pTmp = pData; i2d_X509(pCert, &pTmp); // TODO: Save private key as well res = g_OpenSSL_Token.Storage->Create( fileName, group, CertificateType, pData, len ); TINYCLR_SSL_FREE(pData); if(!res) return CKR_FUNCTION_FAILED; } else { return CKR_FUNCTION_NOT_SUPPORTED; } } else { return CKR_ATTRIBUTE_TYPE_INVALID; } } return CKR_OK; }
CK_RV PKCS11_Objects_OpenSSL::GetAttributeValue(Cryptoki_Session_Context* pSessionCtx, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { OBJECT_DATA* pObj = PKCS11_Objects_OpenSSL::GetObjectFromHandle(pSessionCtx, hObject); if(pObj == NULL) return CKR_OBJECT_HANDLE_INVALID; if(pObj->Type == CertificateType) { CERT_DATA* pCertData = (CERT_DATA*)pObj->Data; X509* pCert = pCertData->cert; INT32 valLen = 0; for(int i=0; i<(int)ulCount; i++) { switch(pTemplate[i].type) { case CKA_CLASS: *(INT32*)pTemplate[i].pValue = SwapEndianIfBEc32(CKO_CERTIFICATE); break; case CKA_PRIVATE: *(INT32*)pTemplate[i].pValue = SwapEndianIfBEc32(pCertData->privKeyData.key == NULL ? 0 : 1); valLen = sizeof(INT32); break; case CKA_VALUE_BITS: { *(INT32*)pTemplate[i].pValue = SwapEndianIfBEc32(pCertData->pubKeyData.size); valLen = sizeof(INT32); } break; case CKA_KEY_TYPE: { *(UINT32*)pTemplate[i].pValue = SwapEndianIfBEc32(pCertData->pubKeyData.type); valLen = sizeof(UINT32); } break; case CKA_ISSUER: { char* name=X509_NAME_oneline(X509_get_issuer_name(pCert),NULL,0); valLen = TINYCLR_SSL_STRLEN(name) + 1; if(valLen > pTemplate[i].ulValueLen) valLen = pTemplate[i].ulValueLen; hal_strcpy_s((char*)pTemplate[i].pValue, valLen, name); OPENSSL_free(name); } break; case CKA_SUBJECT: { char* subject=X509_NAME_oneline(X509_get_subject_name(pCert),NULL,0); valLen = TINYCLR_SSL_STRLEN(subject) + 1; if(valLen > pTemplate[i].ulValueLen) valLen = pTemplate[i].ulValueLen; hal_strcpy_s((char*)pTemplate[i].pValue, valLen, subject); OPENSSL_free(subject); } break; case CKA_SERIAL_NUMBER: { ASN1_INTEGER* asn = X509_get_serialNumber(pCert); valLen = asn->length; if(valLen > pTemplate[i].ulValueLen) valLen = pTemplate[i].ulValueLen; TINYCLR_SSL_MEMCPY(pTemplate[i].pValue, asn->data, valLen); } break; case CKA_MECHANISM_TYPE: if(pCert->sig_alg != NULL) { int signature_nid; CK_MECHANISM_TYPE type = CKM_VENDOR_DEFINED; signature_nid = OBJ_obj2nid(pCert->sig_alg->algorithm); switch(signature_nid) { case NID_sha1WithRSA: case NID_sha1WithRSAEncryption: //szNid = "1.2.840.113549.1.1.5"; type = CKM_SHA1_RSA_PKCS; break; case NID_md5WithRSA: case NID_md5WithRSAEncryption: //szNid = "1.2.840.113549.1.1.4"; type = CKM_MD5_RSA_PKCS; break; case NID_sha256WithRSAEncryption: //szNid = "1.2.840.113549.1.1.11"; type = CKM_SHA256_RSA_PKCS; break; case NID_sha384WithRSAEncryption: //szNid = "1.2.840.113549.1.1.12"; type = CKM_SHA384_RSA_PKCS; break; case NID_sha512WithRSAEncryption: //szNid = "1.2.840.113549.1.1.13"; type = CKM_SHA512_RSA_PKCS; break; } valLen = sizeof(CK_MECHANISM_TYPE); *(CK_MECHANISM_TYPE*)pTemplate[i].pValue = SwapEndianIfBEc32(type); } break; case CKA_START_DATE: { DATE_TIME_INFO dti; ssl_get_ASN1_UTCTIME(X509_get_notBefore(pCert), &dti); valLen = (INT32)pTemplate[i].ulValueLen; if(valLen > sizeof(dti)) valLen = sizeof(dti); TINYCLR_SSL_MEMCPY(pTemplate[i].pValue, &dti, valLen); } break; case CKA_END_DATE: { DATE_TIME_INFO dti; ssl_get_ASN1_UTCTIME(X509_get_notAfter(pCert), &dti); valLen = pTemplate[i].ulValueLen; if(valLen > sizeof(dti)) valLen = sizeof(dti); TINYCLR_SSL_MEMCPY(pTemplate[i].pValue, &dti, valLen); } break; case CKA_VALUE: { UINT8* pData = (UINT8*)pTemplate[i].pValue; UINT8* pTmp = pData; valLen = i2d_X509(pCert, NULL); if(valLen > pTemplate[i].ulValueLen) return CKR_DEVICE_MEMORY; valLen = i2d_X509(pCert, &pTmp); if(valLen < 0) return CKR_FUNCTION_FAILED; } break; case CKA_VALUE_LEN: *(UINT32*)pTemplate[i].pValue = SwapEndianIfBEc32(valLen); break; default: return CKR_ATTRIBUTE_TYPE_INVALID; } } } else if(pObj->Type == KeyType) { KEY_DATA* pKey = (KEY_DATA*)pObj->Data; int valLen = 0; bool isPrivate = false; for(int i=0; i<(int)ulCount; i++) { switch(pTemplate[i].type) { case CKA_CLASS: *(INT32*)pTemplate[i].pValue = SwapEndianIfBEc32((0 != (pKey->attrib & Private) ? CKO_PRIVATE_KEY : 0 != (pKey->attrib & Public) ? CKO_PUBLIC_KEY : CKO_SECRET_KEY)); break; case CKA_MODULUS: if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->n, (UINT8*)pTemplate[i].pValue); } break; case CKA_EXPONENT_1: if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->dmp1, (UINT8*)pTemplate[i].pValue); } break; case CKA_EXPONENT_2: if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->dmq1, (UINT8*)pTemplate[i].pValue); } break; case CKA_COEFFICIENT: if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->iqmp, (UINT8*)pTemplate[i].pValue); } break; case CKA_PRIME_1: if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->p, (UINT8*)pTemplate[i].pValue); } break; case CKA_PRIME_2: if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->q, (UINT8*)pTemplate[i].pValue); } break; case CKA_PRIVATE_EXPONENT: if(pKey->type == CKK_DSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.dsa->priv_key, (UINT8*)pTemplate[i].pValue); } else if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->d, (UINT8*)pTemplate[i].pValue); } break; case CKA_PUBLIC_EXPONENT: if(pKey->type == CKK_DSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.dsa->pub_key, (UINT8*)pTemplate[i].pValue); } else if(pKey->type == CKK_EC) { UINT8 pTmp[66*2+1]; EC_KEY* pEC = ((EVP_PKEY*)pKey->key)->pkey.ec; const EC_POINT* point = EC_KEY_get0_public_key(pEC); valLen = EC_POINT_point2oct(EC_KEY_get0_group(pEC), point, POINT_CONVERSION_UNCOMPRESSED, (UINT8*)pTmp, ARRAYSIZE(pTmp), NULL); if(valLen == 0) return CKR_FUNCTION_FAILED; memmove(pTemplate[i].pValue, &pTmp[1], valLen-1); // remove POINT_CONVERSION_UNCOMPRESSED header byte } else if(pKey->type == CKK_RSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.rsa->e, (UINT8*)pTemplate[i].pValue); } break; case CKA_PRIME: if(pKey->type == CKK_DSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.dsa->p, (UINT8*)pTemplate[i].pValue); } break; case CKA_SUBPRIME: if(pKey->type == CKK_DSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.dsa->q, (UINT8*)pTemplate[i].pValue); } break; case CKA_BASE: if(pKey->type == CKK_DSA) { EVP_PKEY* pRealKey = (EVP_PKEY*)pKey->key; valLen = BN_bn2bin(pRealKey->pkey.dsa->g, (UINT8*)pTemplate[i].pValue); } break; case CKA_PRIVATE: isPrivate = 0 != *(INT32*)pTemplate[i].pValue; break; case CKA_KEY_TYPE: *(INT32*)pTemplate[i].pValue = SwapEndianIfBEc32(pKey->type); break; case CKA_VALUE_BITS: *(UINT32*)pTemplate[i].pValue = SwapEndianIfBEc32(pKey->size); break; case CKA_VALUE: switch(pKey->type) { case CKK_AES: case CKK_GENERIC_SECRET: { // TODO: Add permissions to export key int len = (pKey->size + 7) / 8; if(len > (INT32)pTemplate[i].ulValueLen) len = (int)pTemplate[i].ulValueLen; TINYCLR_SSL_MEMCPY(pTemplate[i].pValue, pKey->key, len); valLen = len; } break; default: return CKR_ATTRIBUTE_TYPE_INVALID; } break; case CKA_VALUE_LEN: switch(pKey->type) { case CKK_EC: *(UINT32*)pTemplate[i].pValue = SwapEndianIfBEc32(valLen); break; default: return CKR_ATTRIBUTE_TYPE_INVALID; } break; default: return CKR_ATTRIBUTE_TYPE_INVALID; } } } return CKR_OK; }
CK_RV PKCS11_Objects_OpenSSL::CreateObject(Cryptoki_Session_Context* pSessionCtx, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject) { UINT32 attribIndex = 0; if(pTemplate[attribIndex].type == CKA_CLASS && pTemplate[attribIndex].ulValueLen == sizeof(CK_OBJECT_CLASS)) { CK_OBJECT_CLASS cls = SwapEndianIfBEc32(*(CK_OBJECT_CLASS*)pTemplate[attribIndex].pValue); CHAR pwd[64]; int len; switch(cls) { case CKO_CERTIFICATE: for(++attribIndex; attribIndex < ulCount; attribIndex++) { switch(pTemplate[attribIndex].type) { case CKA_PASSWORD: len = pTemplate[attribIndex].ulValueLen; if(len >= ARRAYSIZE(pwd)) { len = ARRAYSIZE(pwd) - 1; } TINYCLR_SSL_MEMCPY(pwd, pTemplate[attribIndex].pValue, len); pwd[len] = 0; break; case CKA_VALUE: { OBJECT_DATA* pObject = NULL; EVP_PKEY* privateKey = NULL; X509 *x = ssl_parse_certificate(pTemplate[attribIndex].pValue, pTemplate[attribIndex].ulValueLen, pwd, &privateKey); if (x == NULL) { TINYCLR_SSL_PRINTF("Unable to load certificate\n"); return CKR_FUNCTION_FAILED; } else { CK_RV retVal = LoadX509Cert(pSessionCtx, x, &pObject, privateKey, phObject); if(retVal != CKR_OK) X509_free(x); return retVal; } } } } break; } } return CKR_FUNCTION_NOT_SUPPORTED; }
CK_RV PKCS11_Digest_OpenSSL::DigestInit(Cryptoki_Session_Context* pSessionCtx, CK_MECHANISM_PTR pMechanism) { OPENSSL_HEADER(); OpenSSLDigestData* pDigData; const EVP_MD* pDigest; CK_OBJECT_HANDLE hKey = CK_OBJECT_HANDLE_INVALID; bool isHMAC = false; if(pSessionCtx == NULL) return CKR_SESSION_CLOSED; if(pSessionCtx->DigestCtx != NULL) return CKR_SESSION_PARALLEL_NOT_SUPPORTED; // another digest is in progress pDigData = (OpenSSLDigestData*)TINYCLR_SSL_MALLOC(sizeof(*pDigData)); if(pDigData == NULL) return CKR_DEVICE_MEMORY; TINYCLR_SSL_MEMSET(pDigData, 0, sizeof(*pDigData)); EVP_MD_CTX_init(&pDigData->CurrentCtx); switch(pMechanism->mechanism) { case CKM_SHA_1: pDigest = EVP_sha1(); break; case CKM_SHA224: pDigest = EVP_sha224(); break; case CKM_SHA256: pDigest = EVP_sha256(); break; case CKM_SHA384: pDigest = EVP_sha384(); break; case CKM_SHA512: pDigest = EVP_sha512(); break; case CKM_MD5: pDigest = EVP_md5(); break; case CKM_RIPEMD160: pDigest = EVP_ripemd160(); break; case CKM_MD5_HMAC: pDigest = EVP_md5(); isHMAC = true; break; case CKM_SHA_1_HMAC: pDigest = EVP_sha1(); isHMAC = true; break; case CKM_SHA256_HMAC: pDigest = EVP_sha256(); isHMAC = true; break; case CKM_SHA384_HMAC: pDigest = EVP_sha384(); isHMAC = true; break; case CKM_SHA512_HMAC: pDigest = EVP_sha512(); isHMAC = true; break; case CKM_RIPEMD160_HMAC: pDigest = EVP_ripemd160(); isHMAC = true; break; default: OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_INVALID); } if(isHMAC) { if(pMechanism->pParameter != NULL && pMechanism->ulParameterLen == sizeof(CK_OBJECT_HANDLE)) { hKey = SwapEndianIfBEc32(*(CK_OBJECT_HANDLE*)pMechanism->pParameter); } else { OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_PARAM_INVALID); } pDigData->HmacKey = PKCS11_Keys_OpenSSL::GetKeyFromHandle(pSessionCtx, hKey, TRUE); if(pDigData->HmacKey==NULL) OPENSSL_SET_AND_LEAVE(CKR_MECHANISM_PARAM_INVALID); pDigData->HmacCtx.md = pDigest; OPENSSL_CHECKRESULT(HMAC_Init(&pDigData->HmacCtx, pDigData->HmacKey->key, pDigData->HmacKey->size/8, pDigData->HmacCtx.md)); } else { OPENSSL_CHECKRESULT(EVP_DigestInit_ex(&pDigData->CurrentCtx, pDigest, NULL)); } pSessionCtx->DigestCtx = pDigData; OPENSSL_CLEANUP(); if(retVal != CKR_OK && pDigData != NULL) { TINYCLR_SSL_FREE(pDigData); } OPENSSL_RETURN(); }
int ssl_connect_internal(int sd, const char* szTargetHost, int sslContextHandle) { int err = SOCK_SOCKET_ERROR; SSL *ssl = NULL; int nonblock = 0; // Retrieve SSL struct from g_SSL_Driver if((sslContextHandle >= ARRAYSIZE(g_SSL_Driver.m_sslContextArray)) || (sslContextHandle < 0)) { goto error; } // sd should already have been created // Now do the SSL negotiation ssl = (SSL*)g_SSL_Driver.m_sslContextArray[sslContextHandle].SslContext; if (ssl == NULL) goto error; if (!SSL_set_fd(ssl, sd)) { goto error; } if(ssl->verify_mode != SSL_VERIFY_NONE) { SSL_CTX* pCtx = SSL_get_SSL_CTX(ssl); if(pCtx != NULL) { X509_STORE *pStore = SSL_CTX_get_cert_store(pCtx); if(sk_num(&pStore->objs->stack) == 0) { CryptokiSession* pSession; CK_SLOT_ID slotID; OBJECT_DATA* pObj; CK_ATTRIBUTE attribs[2]; CK_OBJECT_CLASS cls = SwapEndianIfBEc32(CKO_CERTIFICATE); LPSTR label = "CA"; CK_SESSION_HANDLE hSess; if(CKR_OK == C_OpenSession(0, CKF_SERIAL_SESSION, NULL, NULL, &hSess) && CKR_OK == Cryptoki_GetSlotIDFromSession(hSess, &slotID, &pSession)) { attribs[0].type = CKA_CLASS; attribs[0].pValue = &cls; attribs[0].ulValueLen = sizeof(cls); attribs[1].type = CKA_LABEL; attribs[1].pValue = label; attribs[1].ulValueLen = 2; if(CKR_OK == C_FindObjectsInit(hSess, attribs, ARRAYSIZE(attribs))) { CK_OBJECT_HANDLE hObjs[20]; CK_ULONG cnt = 0; if(CKR_OK == C_FindObjects(hSess, hObjs, ARRAYSIZE(hObjs), &cnt) && cnt > 0) { for(int i=0; i<cnt; i++) { pObj = PKCS11_Objects_OpenSSL::GetObjectFromHandle(&pSession->Context, hObjs[i]); if(pObj != NULL && pObj->Type == 3 /*CertificateType*/) { CERT_DATA* pCert = (CERT_DATA*)pObj->Data; X509_STORE_add_cert(pStore, pCert->cert); } } } C_FindObjectsFinal(hSess); } } if(pStore->objs == NULL || 0 == sk_num(&pStore->objs->stack)) { ssl->verify_mode = SSL_VERIFY_NONE; } C_CloseSession(hSess); } } } if(szTargetHost != NULL && szTargetHost[0] != 0) { SSL_set_tlsext_host_name(ssl, szTargetHost); } SOCK_ioctl(sd, SOCK_FIONBIO, &nonblock); err = SSL_connect (ssl); nonblock = 1; SOCK_ioctl(sd, SOCK_FIONBIO, &nonblock); err = SSL_get_error(ssl,err); if(err == SSL_ERROR_WANT_READ) { err = SOCK_EWOULDBLOCK; #if !defined(TCPIP_LWIP) && !defined(TCPIP_LWIP_OS) SOCKET_DRIVER.ClearStatusBitsForSocket( sd, FALSE ); #endif } else if(err == SSL_ERROR_WANT_WRITE) { err = SOCK_TRY_AGAIN; #if !defined(TCPIP_LWIP) && !defined(TCPIP_LWIP_OS) SOCKET_DRIVER.ClearStatusBitsForSocket( sd, TRUE ); #endif } SOCKET_DRIVER.SetSocketSslData(sd, (void*)ssl); error: return err; }
HRESULT Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_FindObjectEnum::FindObjects___SZARRAY_MicrosoftSPOTCryptokiCryptokiObject__I4( CLR_RT_StackFrame& stack ) { TINYCLR_HEADER(); CLR_RT_HeapBlock* pThis = stack.This(); CLR_RT_HeapBlock* pSession = pThis[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_FindObjectEnum::FIELD__m_session].Dereference(); CLR_RT_HeapBlock ref, *pRef; CK_SESSION_HANDLE hSession; CK_ULONG cntObj = (CK_ULONG)stack.Arg1().NumericByRef().u4; CK_OBJECT_HANDLE objs[128]; CK_OBJECT_CLASS objType = CKO_DATA; CLR_INT32 i; CLR_RT_TypeDef_Index objIndex = g_CLR_RT_WellKnownTypes.m_CryptokiObject; BOOL isKey = FALSE; CK_ATTRIBUTE attribs[] = { { CKA_CLASS, &objType, sizeof(objType) }, }; FAULT_ON_NULL(pSession); if(cntObj > ARRAYSIZE(objs)) TINYCLR_SET_AND_LEAVE(CLR_E_OUT_OF_RANGE); hSession = pSession[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_Session::FIELD__m_handle].NumericByRef().u4; CRYPTOKI_CHECK_RESULT(stack, C_FindObjects(hSession, objs, cntObj, &cntObj )); CRYPTOKI_CHECK_RESULT(stack, C_GetAttributeValue(hSession, objs[0], attribs, ARRAYSIZE(attribs))); SwapEndianAndAssignIfBEc32(objType, objType); switch(objType) { case CKO_CERTIFICATE: objIndex = g_CLR_RT_WellKnownTypes.m_CryptokiCertificate; break; case CKO_PRIVATE_KEY: case CKO_PUBLIC_KEY: case CKO_SECRET_KEY: case CKO_OTP_KEY: objIndex = g_CLR_RT_WellKnownTypes.m_CryptoKey; isKey = TRUE; break; } TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance(ref, (CLR_UINT32)cntObj, objIndex)); if(cntObj == 0) { stack.SetResult_Object(ref.DereferenceArray()); TINYCLR_SET_AND_LEAVE(S_OK); } pRef = (CLR_RT_HeapBlock*)ref.DereferenceArray()->GetFirstElement(); for(i=0; i<(INT32)cntObj; i++) { CLR_RT_HeapBlock *pObject; TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex( *pRef, objIndex )); pObject = pRef->Dereference(); pObject[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_CryptokiObject::FIELD__m_handle ].SetInteger((CLR_INT32)objs[i]); pObject[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_session ].SetObjectReference(pSession); pObject[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_ownsSession ].SetBoolean(false); pObject[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_isDisposed ].SetBoolean(false); pObject[Library_security_pkcs11_native_Microsoft_SPOT_Cryptoki_SessionContainer::FIELD__m_isSessionClosing].SetBoolean(false); if(isKey) { CK_ULONG keySize = (CK_ULONG)-1; CK_ULONG keyType = (CK_ULONG)-1; CK_ATTRIBUTE attribs[] = { { CKA_VALUE_BITS, &keySize, sizeof(keySize) }, { CKA_KEY_TYPE , &keyType, sizeof(keyType) }, }; pObject[Library_security_pkcs11_native_System_Security_Cryptography_CryptoKey::FIELD__m_keyType].NumericByRef().s4 = SwapEndianIfBEc32(keyType); C_GetAttributeValue(hSession, objs[i], attribs, ARRAYSIZE(attribs)); pObject[Library_security_pkcs11_native_System_Security_Cryptography_CryptoKey::FIELD__m_length].NumericByRef().u4 = SwapEndianIfBEc32(keySize); switch(objType) { case CKO_PRIVATE_KEY: pObject[Library_security_pkcs11_native_System_Security_Cryptography_CryptoKey::FIELD__m_privateKeyHandle].NumericByRef().u4 = objs[i]; break; case CKO_PUBLIC_KEY: case CKO_SECRET_KEY: default: pObject[Library_security_pkcs11_native_System_Security_Cryptography_CryptoKey::FIELD__m_privateKeyHandle].NumericByRef().u4 = CK_OBJECT_HANDLE_INVALID; break; } } else if(objType == CKO_CERTIFICATE) { CK_ULONG keySize = (CK_ULONG)-1; CK_ULONG keyType = (CK_ULONG)-1; BOOL isPrivate = FALSE; CK_ATTRIBUTE attribs[] = { { CKA_VALUE_BITS, &keySize, sizeof(keySize)}, { CKA_KEY_TYPE , &keyType, sizeof(keyType)}, { CKA_PRIVATE , &isPrivate, sizeof(isPrivate)}, }; C_GetAttributeValue(hSession, objs[i], attribs, ARRAYSIZE(attribs)); pObject[Library_security_pkcs11_native_System_Security_Cryptography_CryptoKey::FIELD__m_keyType].NumericByRef().s4 = SwapEndianIfBEc32(keyType); pObject[Library_security_pkcs11_native_System_Security_Cryptography_CryptoKey::FIELD__m_length].NumericByRef().u4 = SwapEndianIfBEc32(keySize); if(isPrivate == TRUE) { pObject[Library_security_pkcs11_native_System_Security_Cryptography_CryptoKey::FIELD__m_privateKeyHandle].NumericByRef().u4 = objs[i]; } else { pObject[Library_security_pkcs11_native_System_Security_Cryptography_CryptoKey::FIELD__m_privateKeyHandle].NumericByRef().u4 = CK_OBJECT_HANDLE_INVALID; } } pRef++; } stack.SetResult_Object(ref.DereferenceArray()); TINYCLR_NOCLEANUP(); }
/* C_CreateObject creates a new object. */ CK_DEFINE_FUNCTION(CK_RV, C_CreateObject) ( CK_SESSION_HANDLE hSession, /* the session's handle */ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */ CK_ULONG ulCount, /* attributes in template */ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */ ) { CK_RV ret; CK_SLOT_ID slotID; CryptokiSession* pSession; CK_ULONG i = 0; ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession); if(ret != CKR_OK) return ret; if(pTemplate == NULL ) return CKR_ARGUMENTS_BAD; if(phObject == NULL ) return CKR_ARGUMENTS_BAD; *phObject = (CK_OBJECT_HANDLE)-1; if(pTemplate[i].type == CKA_CLASS && pTemplate[i].ulValueLen == sizeof(CK_OBJECT_CLASS)) { CK_OBJECT_CLASS cls = SwapEndianIfBEc32(*(CK_OBJECT_CLASS*)pTemplate[i].pValue); i++; if(i > ulCount) return CKR_ARGUMENTS_BAD; switch(cls) { case CKO_SECRET_KEY: if(pSession->Token->KeyMgmt != NULL && pSession->Token->KeyMgmt->LoadSecretKey != NULL ) { if(pTemplate[i].type == CKA_KEY_TYPE) { CK_KEY_TYPE type = SwapEndianIfBEc32(*(CK_KEY_TYPE*)pTemplate[i].pValue); i++; if(i > ulCount) return CKR_ARGUMENTS_BAD; if(pTemplate[i].type == CKA_VALUE) { ret = pSession->Token->KeyMgmt->LoadSecretKey(&pSession->Context, type, (const UINT8*)pTemplate[i].pValue, pTemplate[i].ulValueLen, phObject); #ifdef _DEBUG if(ret == CKR_OK) { pSession->AddObjectHandle(*phObject); } #endif return ret; } } } break; case CKO_PRIVATE_KEY: case CKO_PUBLIC_KEY: if(pSession->Token->KeyMgmt != NULL) { if(pTemplate[i].type == CKA_KEY_TYPE) { CK_KEY_TYPE type = SwapEndianIfBEc32(*(CK_KEY_TYPE*)pTemplate[i].pValue); bool bPrivate = (cls == CKO_PRIVATE_KEY); if(type == CKK_DSA && pSession->Token->KeyMgmt->LoadDsaKey != NULL) { DsaKeyData dsaKeyData; memset(&dsaKeyData, 0, sizeof(dsaKeyData)); i++; for(;i<ulCount; i++) { switch(pTemplate[i].type) { case CKA_PRIME: dsaKeyData.Prime_p = (PBYTE)pTemplate[i].pValue; dsaKeyData.Prime_p_len = pTemplate[i].ulValueLen; break; case CKA_SUBPRIME: dsaKeyData.Subprime_q = (PBYTE)pTemplate[i].pValue; dsaKeyData.Subprime_q_len = pTemplate[i].ulValueLen; break; case CKA_BASE: dsaKeyData.Base_g = (PBYTE)pTemplate[i].pValue; dsaKeyData.Base_g_len = pTemplate[i].ulValueLen; break; case CKA_PRIVATE_EXPONENT: dsaKeyData.Private_x = (PBYTE)pTemplate[i].pValue; dsaKeyData.Private_x_len = pTemplate[i].ulValueLen; break; case CKA_VALUE: if(bPrivate) { dsaKeyData.Private_x = (PBYTE)pTemplate[i].pValue; dsaKeyData.Private_x_len = pTemplate[i].ulValueLen; } else { dsaKeyData.Public_y = (PBYTE)pTemplate[i].pValue; dsaKeyData.Public_y_len = pTemplate[i].ulValueLen; } break; // public and private in same key case CKA_PUBLIC_EXPONENT: if(bPrivate) { dsaKeyData.Public_y = (PBYTE)pTemplate[i].pValue; dsaKeyData.Public_y_len = pTemplate[i].ulValueLen; } break; } } dsaKeyData.Seed_len = dsaKeyData.Base_g_len; ret = pSession->Token->KeyMgmt->LoadDsaKey(&pSession->Context, dsaKeyData, bPrivate, phObject); #ifdef _DEBUG if(ret == CKR_OK) { pSession->AddObjectHandle(*phObject); } #endif return ret; } else if(type == CKK_RSA && pSession->Token->KeyMgmt->LoadRsaKey != NULL) { PBYTE pRawData = NULL; CK_ULONG rawDataLen = 0; RsaKeyData pParams; memset(&pParams, 0, sizeof(pParams)); i++; for(;i<ulCount; i++) { switch(pTemplate[i].type) { case CKA_MODULUS: pParams.Modulus = (PBYTE)pTemplate[i].pValue; pParams.Modulus_len = pTemplate[i].ulValueLen; break; case CKA_PUBLIC_EXPONENT: pParams.PublicExponent = (PBYTE)pTemplate[i].pValue; pParams.PublicExponent_len = pTemplate[i].ulValueLen; break; case CKA_PRIVATE_EXPONENT: pParams.PrivateExponent = (PBYTE)pTemplate[i].pValue; pParams.PrivateExponent_len = pTemplate[i].ulValueLen; break; case CKA_PRIME_1: pParams.Prime1 = (PBYTE)pTemplate[i].pValue; pParams.Prime1_len = pTemplate[i].ulValueLen; break; case CKA_PRIME_2: pParams.Prime2 = (PBYTE)pTemplate[i].pValue; pParams.Prime2_len = pTemplate[i].ulValueLen; break; case CKA_EXPONENT_1: pParams.Exponent1 = (PBYTE)pTemplate[i].pValue; pParams.Exponent1_len = pTemplate[i].ulValueLen; break; case CKA_EXPONENT_2: pParams.Exponent2 = (PBYTE)pTemplate[i].pValue; pParams.Exponent2_len = pTemplate[i].ulValueLen; break; case CKA_COEFFICIENT: pParams.Coefficient = (PBYTE)pTemplate[i].pValue; pParams.Coefficient_len = pTemplate[i].ulValueLen; break; case CKA_VALUE: pRawData = (PBYTE)pTemplate[i].pValue; rawDataLen = pTemplate[i].ulValueLen; break; } } if(pRawData != NULL && rawDataLen > 0) { ret = pSession->Token->KeyMgmt->LoadKeyBlob(&pSession->Context, pRawData, rawDataLen, CKK_RSA, Public, phObject); } else { ret = pSession->Token->KeyMgmt->LoadRsaKey(&pSession->Context, pParams, bPrivate, phObject); } #ifdef _DEBUG if(ret == CKR_OK) { pSession->AddObjectHandle(*phObject); } #endif return ret; } } } break; } } // give the drivers object management a chance to handle this if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->CreateObject != NULL) { ret = pSession->Token->ObjectMgmt->CreateObject(&pSession->Context, pTemplate, ulCount, phObject); #ifdef _DEBUG if(ret == CKR_OK) { pSession->AddObjectHandle(*phObject); } #endif return ret; } return CKR_FUNCTION_NOT_SUPPORTED; }