/* Retrieve EC point from key into ec * return nonzero on error */ static int pkcs11_get_point_key(EC_KEY *ec, PKCS11_KEY *key) { CK_BYTE *point; size_t point_len = 0; const unsigned char *a; ASN1_OCTET_STRING *os; int rv = -1; if (key == NULL || key_getattr_alloc(key, CKA_EC_POINT, &point, &point_len)) return -1; /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ a = point; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)point_len); if (os) { a = os->data; rv = o2i_ECPublicKey(&ec, &a, os->length) == NULL; ASN1_STRING_free(os); } if (rv) { /* Workaround for broken PKCS#11 modules */ a = point; rv = o2i_ECPublicKey(&ec, &a, (long)point_len) == NULL; } OPENSSL_free(point); return rv; }
static EC_KEY *pkcs11_get_ec(PKCS11_KEY *key) { EC_KEY *ec, *found_params = NULL, *found_point = NULL; CK_BYTE *params, *point; size_t params_len = 0, point_len = 0; PKCS11_KEY *pubkey; ec = EC_KEY_new(); if (ec == NULL) return NULL; /* For OpenSSL req we need at least the * EC_KEY_get0_group(ec_key)) to return the group. * Continue even if it fails, as the sign operation does not need * it if the PKCS#11 module or the hardware can figure this out */ if (!key_getattr_alloc(key, CKA_EC_PARAMS, ¶ms, ¶ms_len)) { const unsigned char *a = params; /* Convert to OpenSSL parmas */ found_params = d2i_ECParameters(&ec, &a, (long)params_len); OPENSSL_free(params); } /* Now retrieve the point */ pubkey = key->isPrivate ? pkcs11_find_key_from_key(key) : key; if (pubkey == NULL) return ec; if (!key_getattr_alloc(pubkey, CKA_EC_POINT, &point, &point_len)) { const unsigned char *a; ASN1_OCTET_STRING *os; /* PKCS#11-compliant modules should return ASN1_OCTET_STRING */ a = point; os = d2i_ASN1_OCTET_STRING(NULL, &a, (long)point_len); if (os) { a = os->data; found_point = o2i_ECPublicKey(&ec, &a, os->length); ASN1_STRING_free(os); } if (found_point == NULL) { /* Workaround for broken PKCS#11 modules */ a = point; found_point = o2i_ECPublicKey(&ec, &a, point_len); } OPENSSL_free(point); } /* A public keys requires both the params and the point to be present */ if (!key->isPrivate && (found_params == NULL || found_point == NULL)) { EC_KEY_free(ec); return NULL; } return ec; }
/* Retrieve EC parameters from key into ec * return nonzero on error */ static int pkcs11_get_params(EC_KEY *ec, PKCS11_KEY *key) { CK_BYTE *params; size_t params_len = 0; const unsigned char *a; int rv; if (key_getattr_alloc(key, CKA_EC_PARAMS, ¶ms, ¶ms_len)) return -1; a = params; rv = d2i_ECParameters(&ec, &a, (long)params_len) == NULL; OPENSSL_free(params); return rv; }