/* * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "asymmetric_key.h" #include #include #include "openssl_err.h" #include "openssl_utils.h" namespace keymaster { keymaster_error_t AsymmetricKey::key_material(UniquePtr* material, size_t* size) const { if (material == NULL || size == NULL) return KM_ERROR_OUTPUT_PARAMETER_NULL; UniquePtr pkey(EVP_PKEY_new()); if (pkey.get() == NULL) return KM_ERROR_MEMORY_ALLOCATION_FAILED; if (!InternalToEvp(pkey.get())) return TranslateLastOpenSslError(); *size = i2d_PrivateKey(pkey.get(), NULL /* key_data*/); if (*size <= 0) return TranslateLastOpenSslError(); material->reset(new (std::nothrow) uint8_t[*size]); uint8_t* tmp = material->get(); i2d_PrivateKey(pkey.get(), &tmp); return KM_ERROR_OK; } keymaster_error_t AsymmetricKey::formatted_key_material(keymaster_key_format_t format, UniquePtr* material, size_t* size) const { if (format != KM_KEY_FORMAT_X509) return KM_ERROR_UNSUPPORTED_KEY_FORMAT; if (material == NULL || size == NULL) return KM_ERROR_OUTPUT_PARAMETER_NULL; UniquePtr pkey(EVP_PKEY_new()); if (!InternalToEvp(pkey.get())) return TranslateLastOpenSslError(); int key_data_length = i2d_PUBKEY(pkey.get(), NULL); if (key_data_length <= 0) return TranslateLastOpenSslError(); material->reset(new (std::nothrow) uint8_t[key_data_length]); if (material->get() == NULL) return KM_ERROR_MEMORY_ALLOCATION_FAILED; uint8_t* tmp = material->get(); if (i2d_PUBKEY(pkey.get(), &tmp) != key_data_length) { material->reset(); return TranslateLastOpenSslError(); } *size = key_data_length; return KM_ERROR_OK; } } // namespace keymaster