📄 mechanism.c
字号:
free(data); return rv; } data->info = info; } operation->priv_data = data; return CKR_OK;}static CK_RVsc_pkcs11_signature_update(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pPart, CK_ULONG ulPartLen){ struct signature_data *data; data = (struct signature_data *) operation->priv_data; if (data->md) { sc_pkcs11_operation_t *md = data->md; return md->type->md_update(md, pPart, ulPartLen); } /* This signature mechanism operates on the raw data */ if (data->buffer_len + ulPartLen > sizeof(data->buffer)) return CKR_DATA_LEN_RANGE; memcpy(data->buffer + data->buffer_len, pPart, ulPartLen); data->buffer_len += ulPartLen; return CKR_OK;}static CK_RVsc_pkcs11_signature_final(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen){ struct signature_data *data; struct sc_pkcs11_object *key; int rv; data = (struct signature_data *) operation->priv_data; if (data->md) { sc_pkcs11_operation_t *md = data->md; CK_ULONG len = sizeof(data->buffer); rv = md->type->md_final(md, data->buffer, &len); if (rv == CKR_BUFFER_TOO_SMALL) rv = CKR_FUNCTION_FAILED; if (rv != CKR_OK) return rv; data->buffer_len = len; } key = data->key; return key->ops->sign(operation->session, key, &operation->mechanism, data->buffer, data->buffer_len, pSignature, pulSignatureLen);}static CK_RVsc_pkcs11_signature_size(sc_pkcs11_operation_t *operation, CK_ULONG_PTR pLength){ struct sc_pkcs11_object *key; CK_ATTRIBUTE attr = { CKA_MODULUS_BITS, pLength, sizeof(*pLength) }; CK_RV rv; key = ((struct signature_data *) operation->priv_data)->key; rv = key->ops->get_attribute(operation->session, key, &attr); /* convert bits to bytes */ if (rv == CKR_OK) *pLength = (*pLength + 7) / 8; return rv;}static voidsc_pkcs11_signature_release(sc_pkcs11_operation_t *operation){ struct signature_data *data; data = (struct signature_data *) operation->priv_data; sc_pkcs11_release_operation(&data->md); memset(data, 0, sizeof(*data)); free(data);}#ifdef HAVE_OPENSSL/* * Initialize a verify context. When we get here, we know * the key object is capable of verifying _something_ */CK_RVsc_pkcs11_verif_init(struct sc_pkcs11_session *session, CK_MECHANISM_PTR pMechanism, struct sc_pkcs11_object *key, CK_MECHANISM_TYPE key_type){ struct sc_pkcs11_card *p11card; sc_pkcs11_operation_t *operation; sc_pkcs11_mechanism_type_t *mt; int rv; if (!session || !session->slot || !(p11card = session->slot->card)) return CKR_ARGUMENTS_BAD; /* See if we support this mechanism type */ mt = sc_pkcs11_find_mechanism(p11card, pMechanism->mechanism, CKF_VERIFY); if (mt == NULL) return CKR_MECHANISM_INVALID; /* See if compatible with key type */ if (mt->key_type != key_type) return CKR_KEY_TYPE_INCONSISTENT; rv = session_start_operation(session, SC_PKCS11_OPERATION_VERIFY, mt, &operation); if (rv != CKR_OK) return rv; memcpy(&operation->mechanism, pMechanism, sizeof(CK_MECHANISM)); rv = mt->verif_init(operation, key); if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_VERIFY); return rv;}CK_RVsc_pkcs11_verif_update(struct sc_pkcs11_session *session, CK_BYTE_PTR pData, CK_ULONG ulDataLen){ sc_pkcs11_operation_t *op; int rv; rv = session_get_operation(session, SC_PKCS11_OPERATION_VERIFY, &op); if (rv != CKR_OK) return rv; if (op->type->verif_update == NULL) { rv = CKR_KEY_TYPE_INCONSISTENT; goto done; } rv = op->type->verif_update(op, pData, ulDataLen);done: if (rv != CKR_OK) session_stop_operation(session, SC_PKCS11_OPERATION_VERIFY); return rv;}CK_RVsc_pkcs11_verif_final(struct sc_pkcs11_session *session, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen){ sc_pkcs11_operation_t *op; int rv; rv = session_get_operation(session, SC_PKCS11_OPERATION_VERIFY, &op); if (rv != CKR_OK) return rv; if (op->type->verif_final == NULL) { rv = CKR_KEY_TYPE_INCONSISTENT; goto done; } rv = op->type->verif_final(op, pSignature, ulSignatureLen);done: session_stop_operation(session, SC_PKCS11_OPERATION_VERIFY); return rv;}/* * Initialize a signature operation */static CK_RVsc_pkcs11_verify_init(sc_pkcs11_operation_t *operation, struct sc_pkcs11_object *key){ struct hash_signature_info *info; struct signature_data *data; int rv; if (!(data = (struct signature_data *) calloc(1, sizeof(*data)))) return CKR_HOST_MEMORY; data->info = NULL; data->key = key; /* If this is a verify with hash operation, set up the * hash operation */ info = (struct hash_signature_info *) operation->type->mech_data; if (info != NULL) { /* Initialize hash operation */ data->md = sc_pkcs11_new_operation(operation->session, info->hash_type); if (data->md == NULL) rv = CKR_HOST_MEMORY; else rv = info->hash_type->md_init(data->md); if (rv != CKR_OK) { sc_pkcs11_release_operation(&data->md); free(data); return rv; } data->info = info; } operation->priv_data = data; return CKR_OK;}static CK_RVsc_pkcs11_verify_update(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pPart, CK_ULONG ulPartLen){ struct signature_data *data; data = (struct signature_data *) operation->priv_data; if (data->md) { sc_pkcs11_operation_t *md = data->md; return md->type->md_update(md, pPart, ulPartLen); } /* This verification mechanism operates on the raw data */ if (data->buffer_len + ulPartLen > sizeof(data->buffer)) return CKR_DATA_LEN_RANGE; memcpy(data->buffer + data->buffer_len, pPart, ulPartLen); data->buffer_len += ulPartLen; return CKR_OK;}static CK_RVsc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen){ struct signature_data *data; struct sc_pkcs11_object *key; unsigned char *pubkey_value; CK_ATTRIBUTE attr = {CKA_VALUE, NULL, 0}; int rv; data = (struct signature_data *) operation->priv_data; if (pSignature == NULL) return CKR_ARGUMENTS_BAD; key = data->key; rv = key->ops->get_attribute(operation->session, key, &attr); if (rv != CKR_OK) return rv; pubkey_value = (unsigned char *) malloc(attr.ulValueLen); attr.pValue = pubkey_value; rv = key->ops->get_attribute(operation->session, key, &attr); if (rv != CKR_OK) goto done; rv = sc_pkcs11_verify_data(pubkey_value, attr.ulValueLen, operation->mechanism.mechanism, data->md, data->buffer, data->buffer_len, pSignature, ulSignatureLen);done: free(pubkey_value); return rv;}#endif/* * Create new mechanism type for a mechanism supported by * the card */sc_pkcs11_mechanism_type_t *sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech, CK_MECHANISM_INFO_PTR pInfo, CK_KEY_TYPE key_type, void *priv_data){ sc_pkcs11_mechanism_type_t *mt; mt = (sc_pkcs11_mechanism_type_t *) calloc(1, sizeof(*mt)); if (mt == NULL) return mt; mt->mech = mech; mt->mech_info = *pInfo; mt->key_type = key_type; mt->mech_data = priv_data; mt->obj_size = sizeof(sc_pkcs11_operation_t); mt->release = sc_pkcs11_signature_release; if (pInfo->flags & CKF_SIGN) { mt->sign_init = sc_pkcs11_signature_init; mt->sign_update = sc_pkcs11_signature_update; mt->sign_final = sc_pkcs11_signature_final; mt->sign_size = sc_pkcs11_signature_size;#ifdef HAVE_OPENSSL mt->verif_init = sc_pkcs11_verify_init; mt->verif_update = sc_pkcs11_verify_update; mt->verif_final = sc_pkcs11_verify_final;#endif } if (pInfo->flags & CKF_UNWRAP) { /* ... */ } return mt;}/* * Register generic mechanisms */CK_RVsc_pkcs11_register_generic_mechanisms(struct sc_pkcs11_card *p11card){#ifdef HAVE_OPENSSL sc_pkcs11_register_openssl_mechanisms(p11card);#endif return CKR_OK;}/* * Register a sign+hash algorithm derived from an algorithm supported * by the token + a software hash mechanism */CK_RVsc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card, CK_MECHANISM_TYPE mech, CK_MECHANISM_TYPE hash_mech, sc_pkcs11_mechanism_type_t *sign_type){ sc_pkcs11_mechanism_type_t *hash_type, *new_type; struct hash_signature_info *info; CK_MECHANISM_INFO mech_info = sign_type->mech_info; if (!(hash_type = sc_pkcs11_find_mechanism(p11card, hash_mech, CKF_DIGEST))) return CKR_MECHANISM_INVALID; /* These hash-based mechs can only be used for sign/verify */ mech_info.flags &= (CKF_SIGN | CKF_SIGN_RECOVER | CKF_VERIFY | CKF_VERIFY_RECOVER); info = (struct hash_signature_info *) calloc(1, sizeof(*info)); info->mech = mech; info->sign_type = sign_type; info->hash_type = hash_type; info->sign_mech = sign_type->mech; info->hash_mech = hash_mech; new_type = sc_pkcs11_new_fw_mechanism(mech, &mech_info, sign_type->key_type, info); if (new_type) sc_pkcs11_register_mechanism(p11card, new_type); return CKR_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -