📄 key.c
字号:
secret_key_unwrap( TEMPLATE *tmpl, CK_ULONG keytype, CK_BYTE *data, CK_ULONG data_len, CK_BBOOL fromend ){ CK_ATTRIBUTE *local = NULL; CK_ATTRIBUTE *always_sens = NULL; CK_ATTRIBUTE *sensitive = NULL; CK_ATTRIBUTE *extractable = NULL; CK_ATTRIBUTE *never_extract = NULL; CK_BBOOL true = TRUE; CK_BBOOL false = FALSE; CK_RV rc; switch (keytype) { case CKK_CDMF: case CKK_DES: rc = des_unwrap( tmpl, data, data_len, fromend ); break; case CKK_DES3: rc = des3_unwrap( tmpl, data, data_len, fromend ); break; case CKK_AES: rc = aes_unwrap( tmpl, data, data_len, fromend ); break; case CKK_GENERIC_SECRET: case CKK_RC2: case CKK_RC4: case CKK_RC5: case CKK_CAST: case CKK_CAST3: case CKK_CAST5: rc = generic_secret_unwrap( tmpl, data, data_len, fromend ); break; default: st_err_log(62, __FILE__, __LINE__); return CKR_WRAPPED_KEY_INVALID; } if (rc != CKR_OK) return rc; // make sure // CKA_LOCAL == FALSE // CKA_ALWAYS_SENSITIVE == FALSE // CKA_EXTRACTABLE == TRUE // CKA_NEVER_EXTRACTABLE == FALSE // rc = build_attribute( CKA_LOCAL, &false, 1, &local ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_ALWAYS_SENSITIVE, &false, 1, &always_sens ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_SENSITIVE, &false, 1, &sensitive ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_EXTRACTABLE, &true, 1, &extractable ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } rc = build_attribute( CKA_NEVER_EXTRACTABLE, &false, 1, &never_extract ); if (rc != CKR_OK){ st_err_log(84, __FILE__, __LINE__); goto cleanup; } template_update_attribute( tmpl, local ); template_update_attribute( tmpl, always_sens ); template_update_attribute( tmpl, sensitive ); template_update_attribute( tmpl, extractable ); template_update_attribute( tmpl, never_extract ); return CKR_OK;cleanup: if (local) free(local); if (extractable) free(extractable); if (always_sens) free(always_sens); if (never_extract) free(never_extract); return rc;}// secret_key_validate_attribute()//CK_RVsecret_key_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ){ switch (attr->type) { case CKA_ENCRYPT: case CKA_DECRYPT: case CKA_SIGN: case CKA_VERIFY: case CKA_WRAP: case CKA_UNWRAP: if (mode == MODE_MODIFY) { if (nv_token_data->tweak_vector.allow_key_mods == TRUE) return CKR_OK; st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } return CKR_OK; // after key creation, CKA_SENSITIVE may only be set to TRUE // case CKA_SENSITIVE: { CK_BBOOL value; value = *(CK_BBOOL *)attr->pValue; if ((mode != MODE_CREATE && mode != MODE_DERIVE && mode !=MODE_KEYGEN) && (value != TRUE)){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } } return CKR_OK; // after key creation, CKA_EXTRACTABLE may only be set to FALSE // case CKA_EXTRACTABLE: { CK_BBOOL value; // the unwrap routine will automatically set extractable to TRUE // value = *(CK_BBOOL *)attr->pValue; if ((mode != MODE_CREATE && mode != MODE_DERIVE && mode !=MODE_KEYGEN) && (value != FALSE)){ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } if (value == FALSE) { CK_ATTRIBUTE *attr; attr = (CK_ATTRIBUTE *)malloc(sizeof(CK_ATTRIBUTE) + sizeof(CK_BBOOL) ); if (!attr){ st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } attr->type = CKA_NEVER_EXTRACTABLE; attr->ulValueLen = sizeof(CK_BBOOL); attr->pValue = (CK_BYTE *)attr + sizeof(CK_ATTRIBUTE); *(CK_BBOOL *)attr->pValue = FALSE; template_update_attribute( tmpl, attr ); } } return CKR_OK; case CKA_ALWAYS_SENSITIVE: case CKA_NEVER_EXTRACTABLE: st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; default: return key_object_validate_attribute( tmpl, attr, mode ); } st_err_log(8, __FILE__, __LINE__); return CKR_ATTRIBUTE_TYPE_INVALID;}// secret_key_check_exportability()//CK_BBOOLsecret_key_check_exportability( CK_ATTRIBUTE_TYPE type ){ switch (type) { case CKA_VALUE: st_err_log(86, __FILE__, __LINE__); return FALSE; } return TRUE;}// rsa_publ_check_required_attributes()//CK_RVrsa_publ_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ){ CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_MODULUS, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_MODULUS_BITS, &attr ); if (!found) { if (mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } found = template_attribute_find( tmpl, CKA_PUBLIC_EXPONENT, &attr ); if (!found) { if (mode == MODE_CREATE || mode == MODE_KEYGEN){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } return publ_key_check_required_attributes( tmpl, mode );}// rsa_publ_set_default_attributes()//CK_RVrsa_publ_set_default_attributes( TEMPLATE *tmpl, CK_ULONG mode ){ CK_ATTRIBUTE *type_attr = NULL; CK_ATTRIBUTE *modulus_attr = NULL; CK_ATTRIBUTE *modulus_bits_attr = NULL; CK_ATTRIBUTE *public_exp_attr = NULL; CK_ULONG bits = 0L; publ_key_set_default_attributes( tmpl, mode ); type_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_KEY_TYPE) ); modulus_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); modulus_bits_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) + sizeof(CK_ULONG) ); public_exp_attr = (CK_ATTRIBUTE *)malloc( sizeof(CK_ATTRIBUTE) ); if (!type_attr || !modulus_attr || !modulus_bits_attr || !public_exp_attr) { if (type_attr) free( type_attr ); if (modulus_attr) free( modulus_attr ); if (modulus_bits_attr) free( modulus_bits_attr ); if (public_exp_attr) free( public_exp_attr ); st_err_log(1, __FILE__, __LINE__); return CKR_HOST_MEMORY; } type_attr->type = CKA_KEY_TYPE; type_attr->ulValueLen = sizeof(CK_KEY_TYPE); type_attr->pValue = (CK_BYTE *)type_attr + sizeof(CK_ATTRIBUTE); *(CK_KEY_TYPE *)type_attr->pValue = CKK_RSA; modulus_attr->type = CKA_MODULUS; modulus_attr->ulValueLen = 0; modulus_attr->pValue = NULL; modulus_bits_attr->type = CKA_MODULUS_BITS; modulus_bits_attr->ulValueLen = sizeof(CK_ULONG); modulus_bits_attr->pValue = (CK_BYTE *)modulus_bits_attr + sizeof(CK_ATTRIBUTE); *(CK_ULONG *)modulus_bits_attr->pValue = bits; public_exp_attr->type = CKA_PUBLIC_EXPONENT; public_exp_attr->ulValueLen = 0; public_exp_attr->pValue = NULL; template_update_attribute( tmpl, type_attr ); template_update_attribute( tmpl, modulus_attr ); template_update_attribute( tmpl, modulus_bits_attr ); template_update_attribute( tmpl, public_exp_attr ); return CKR_OK;}// rsa_publ_validate_attributes()//CK_RVrsa_publ_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode ){ switch (attr->type) { case CKA_MODULUS_BITS: if (mode == MODE_KEYGEN) { if (attr->ulValueLen != sizeof(CK_ULONG)){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } else { CK_ULONG mod_bits = *(CK_ULONG *)attr->pValue; if (mod_bits < 512 || mod_bits > 2048){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } if (mod_bits % 8 != 0){ st_err_log(9, __FILE__, __LINE__); return CKR_ATTRIBUTE_VALUE_INVALID; } return CKR_OK; } } else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_MODULUS: if (mode == MODE_CREATE) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } case CKA_PUBLIC_EXPONENT: if (mode == MODE_CREATE || mode == MODE_KEYGEN) return remove_leading_zeros( attr ); else{ st_err_log(7, __FILE__, __LINE__); return CKR_ATTRIBUTE_READ_ONLY; } default: return publ_key_validate_attribute( tmpl, attr, mode ); }}// rsa_priv_check_required_attributes()//CK_RVrsa_priv_check_required_attributes( TEMPLATE *tmpl, CK_ULONG mode ){ CK_ATTRIBUTE *attr = NULL; CK_BBOOL found; found = template_attribute_find( tmpl, CKA_MODULUS, &attr ); if (!found) { if (mode == MODE_CREATE){ st_err_log(48, __FILE__, __LINE__); return CKR_TEMPLATE_INCOMPLETE; } } // // PKCS #11 is flexible with respect to which attributes must be present // in an RSA key. Keys can be specified in Chinese-Remainder format or // they can be specified in modular-exponent format. Right now, I only // support keys created in Chinese-Remainder format. That is, we return // CKR_TEMPLATE_INCOMPLETE if a modular-exponent key is specified. This // is allowed by PKCS #11. // // In the future, we should allow for creation of keys in modular-exponent // format too. This raises some issues. It's easy enough to recognize // when a key has been specified in modular-exponent format. And it's // easy enough to recognize when all attributes have been specified // (which is what we require right now). What's trickier to handle is // the "middle" cases in which more than the minimum yet less than the // full number of attributes have been specified. Do we revert back to // modular-exponent representation? Do we compute the missing attributes // ourselves? Do we simply return CKR_TEMPLATE_INCOMPLETE? //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -