1/* 2 * Copyright 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <openssl/x509.h> 18 19#include <keymaster/key_blob.h> 20 21#include "asymmetric_key.h" 22#include "openssl_utils.h" 23 24#include "key.h" 25 26namespace keymaster { 27 28struct PKCS8_PRIV_KEY_INFO_Delete { 29 void operator()(PKCS8_PRIV_KEY_INFO* p) const { PKCS8_PRIV_KEY_INFO_free(p); } 30}; 31 32Key::Key(const KeyBlob& blob, const Logger& logger) : logger_(logger) { 33 authorizations_.push_back(blob.unenforced()); 34 authorizations_.push_back(blob.enforced()); 35} 36 37/* static */ 38Key* Key::CreateKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error) { 39 switch (blob.algorithm()) { 40 case KM_ALGORITHM_RSA: 41 return new RsaKey(blob, logger, error); 42 case KM_ALGORITHM_DSA: 43 return new DsaKey(blob, logger, error); 44 case KM_ALGORITHM_ECDSA: 45 return new EcdsaKey(blob, logger, error); 46 default: 47 *error = KM_ERROR_UNSUPPORTED_ALGORITHM; 48 return NULL; 49 } 50} 51 52/* static */ 53Key* Key::GenerateKey(const AuthorizationSet& key_description, const Logger& logger, 54 keymaster_error_t* error) { 55 keymaster_algorithm_t algorithm; 56 if (!key_description.GetTagValue(TAG_ALGORITHM, &algorithm)) { 57 *error = KM_ERROR_UNSUPPORTED_ALGORITHM; 58 return NULL; 59 } 60 61 switch (algorithm) { 62 case KM_ALGORITHM_RSA: 63 return RsaKey::GenerateKey(key_description, logger, error); 64 case KM_ALGORITHM_DSA: 65 return DsaKey::GenerateKey(key_description, logger, error); 66 case KM_ALGORITHM_ECDSA: 67 return EcdsaKey::GenerateKey(key_description, logger, error); 68 default: 69 *error = KM_ERROR_UNSUPPORTED_ALGORITHM; 70 return NULL; 71 } 72} 73 74/* static */ 75Key* Key::ImportKey(const AuthorizationSet& key_description, keymaster_key_format_t key_format, 76 const uint8_t* key_data, size_t key_data_length, const Logger& logger, 77 keymaster_error_t* error) { 78 *error = KM_ERROR_OK; 79 80 if (key_data == NULL || key_data_length <= 0) { 81 *error = KM_ERROR_INVALID_KEY_BLOB; 82 return NULL; 83 } 84 85 if (key_format != KM_KEY_FORMAT_PKCS8) { 86 *error = KM_ERROR_UNSUPPORTED_KEY_FORMAT; 87 return NULL; 88 } 89 90 UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> pkcs8( 91 d2i_PKCS8_PRIV_KEY_INFO(NULL, &key_data, key_data_length)); 92 if (pkcs8.get() == NULL) { 93 *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 94 return NULL; 95 } 96 97 UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKCS82PKEY(pkcs8.get())); 98 if (pkey.get() == NULL) { 99 *error = KM_ERROR_INVALID_KEY_BLOB; 100 return NULL; 101 } 102 103 UniquePtr<Key> key; 104 switch (EVP_PKEY_type(pkey->type)) { 105 case EVP_PKEY_RSA: 106 return RsaKey::ImportKey(key_description, pkey.get(), logger, error); 107 case EVP_PKEY_DSA: 108 return DsaKey::ImportKey(key_description, pkey.get(), logger, error); 109 case EVP_PKEY_EC: 110 return EcdsaKey::ImportKey(key_description, pkey.get(), logger, error); 111 default: 112 *error = KM_ERROR_UNSUPPORTED_ALGORITHM; 113 return NULL; 114 } 115 116 *error = KM_ERROR_UNIMPLEMENTED; 117 return NULL; 118} 119 120} // namespace keymaster 121