Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
halo
system_security
Commits
9fae4d99
Commit
9fae4d99
authored
8 years ago
by
Treehugger Robot
Committed by
Gerrit Code Review
8 years ago
Browse files
Options
Download
Plain Diff
Merge "Remove OpenSSL support"
parents
71251eec
ddf4742f
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
2 additions
and
890 deletions
+2
-890
keystore-engine/Android.mk
keystore-engine/Android.mk
+2
-25
keystore-engine/dsa_meth.cpp
keystore-engine/dsa_meth.cpp
+0
-152
keystore-engine/ecdsa_meth.cpp
keystore-engine/ecdsa_meth.cpp
+0
-155
keystore-engine/eng_keystore.cpp
keystore-engine/eng_keystore.cpp
+0
-238
keystore-engine/keyhandle.cpp
keystore-engine/keyhandle.cpp
+0
-78
keystore-engine/rsa_meth.cpp
keystore-engine/rsa_meth.cpp
+0
-242
No files found.
keystore-engine/Android.mk
View file @
9fae4d99
...
...
@@ -16,33 +16,10 @@ LOCAL_PATH := $(call my-dir)
include
$(CLEAR_VARS)
LOCAL_MODULE
:=
libkeystore-engine
ifneq
(,$(wildcard $(TOP)/external/boringssl/flavor.mk))
include
$(TOP)/external/boringssl/flavor.mk
else
include
$(TOP)/external/openssl/flavor.mk
endif
ifeq
($(OPENSSL_FLAVOR),BoringSSL)
LOCAL_MODULE
:=
libkeystore-engine
LOCAL_SRC_FILES
:=
\
LOCAL_SRC_FILES
:=
\
android_engine.cpp
else
LOCAL_MODULE
:=
libkeystore
LOCAL_MODULE_RELATIVE_PATH
:=
ssl/engines
LOCAL_SRC_FILES
:=
\
eng_keystore.cpp
\
keyhandle.cpp
\
ecdsa_meth.cpp
\
dsa_meth.cpp
\
rsa_meth.cpp
LOCAL_C_INCLUDES
+=
\
external/openssl/include
\
external/openssl
endif
LOCAL_MODULE_TAGS
:=
optional
LOCAL_CFLAGS
:=
-fvisibility
=
hidden
-Wall
-Werror
...
...
This diff is collapsed.
Click to expand it.
keystore-engine/dsa_meth.cpp
deleted
100644 → 0
View file @
71251eec
/*
* Copyright 2013 The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <UniquePtr.h>
//#define LOG_NDEBUG 0
#define LOG_TAG "OpenSSL-keystore-dsa"
#include <cutils/log.h>
#include <binder/IServiceManager.h>
#include <keystore/IKeystoreService.h>
#include <openssl/dsa.h>
#include <openssl/engine.h>
#include "methods.h"
using
namespace
android
;
struct
DSA_SIG_Delete
{
void
operator
()(
DSA_SIG
*
p
)
const
{
DSA_SIG_free
(
p
);
}
};
typedef
UniquePtr
<
DSA_SIG
,
struct
DSA_SIG_Delete
>
Unique_DSA_SIG
;
static
DSA_SIG
*
keystore_dsa_do_sign
(
const
unsigned
char
*
dgst
,
int
dlen
,
DSA
*
dsa
)
{
ALOGV
(
"keystore_dsa_do_sign(%p, %d, %p)"
,
dgst
,
dlen
,
dsa
);
uint8_t
*
key_id
=
reinterpret_cast
<
uint8_t
*>
(
DSA_get_ex_data
(
dsa
,
dsa_key_handle
));
if
(
key_id
==
NULL
)
{
ALOGE
(
"key had no key_id!"
);
return
0
;
}
sp
<
IServiceManager
>
sm
=
defaultServiceManager
();
sp
<
IBinder
>
binder
=
sm
->
getService
(
String16
(
"android.security.keystore"
));
sp
<
IKeystoreService
>
service
=
interface_cast
<
IKeystoreService
>
(
binder
);
if
(
service
==
NULL
)
{
ALOGE
(
"could not contact keystore"
);
return
0
;
}
int
num
=
DSA_size
(
dsa
);
uint8_t
*
reply
=
NULL
;
size_t
replyLen
;
int32_t
ret
=
service
->
sign
(
String16
(
reinterpret_cast
<
const
char
*>
(
key_id
)),
dgst
,
dlen
,
&
reply
,
&
replyLen
);
if
(
ret
<
0
)
{
ALOGW
(
"There was an error during dsa_do_sign: could not connect"
);
return
0
;
}
else
if
(
ret
!=
0
)
{
ALOGW
(
"Error during sign from keystore: %d"
,
ret
);
return
0
;
}
else
if
(
replyLen
<=
0
)
{
ALOGW
(
"No valid signature returned"
);
return
0
;
}
else
if
(
replyLen
>
(
size_t
)
num
)
{
ALOGW
(
"Signature is too large"
);
return
0
;
}
Unique_DSA_SIG
dsa_sig
(
d2i_DSA_SIG
(
NULL
,
const_cast
<
const
unsigned
char
**>
(
reinterpret_cast
<
unsigned
char
**>
(
&
reply
)),
replyLen
));
if
(
dsa_sig
.
get
()
==
NULL
)
{
ALOGW
(
"conversion from DER to DSA_SIG failed"
);
return
0
;
}
ALOGV
(
"keystore_dsa_do_sign(%p, %d, %p) => returning %p len %zu"
,
dgst
,
dlen
,
dsa
,
dsa_sig
.
get
(),
replyLen
);
return
dsa_sig
.
release
();
}
static
DSA_METHOD
keystore_dsa_meth
=
{
kKeystoreEngineId
,
/* name */
keystore_dsa_do_sign
,
/* dsa_do_sign */
NULL
,
/* dsa_sign_setup */
NULL
,
/* dsa_do_verify */
NULL
,
/* dsa_mod_exp */
NULL
,
/* bn_mod_exp */
NULL
,
/* init */
NULL
,
/* finish */
0
,
/* flags */
NULL
,
/* app_data */
NULL
,
/* dsa_paramgen */
NULL
,
/* dsa_keygen */
};
static
int
register_dsa_methods
()
{
const
DSA_METHOD
*
dsa_meth
=
DSA_OpenSSL
();
keystore_dsa_meth
.
dsa_do_verify
=
dsa_meth
->
dsa_do_verify
;
return
1
;
}
int
dsa_pkey_setup
(
ENGINE
*
e
,
EVP_PKEY
*
pkey
,
const
char
*
key_id
)
{
Unique_DSA
dsa
(
EVP_PKEY_get1_DSA
(
pkey
));
if
(
!
DSA_set_ex_data
(
dsa
.
get
(),
dsa_key_handle
,
reinterpret_cast
<
void
*>
(
strdup
(
key_id
))))
{
ALOGW
(
"Could not set ex_data for loaded DSA key"
);
return
0
;
}
DSA_set_method
(
dsa
.
get
(),
&
keystore_dsa_meth
);
/*
* "DSA_set_ENGINE()" should probably be an OpenSSL API. Since it isn't,
* and EVP_PKEY_free() calls ENGINE_finish(), we need to call ENGINE_init()
* here.
*/
ENGINE_init
(
e
);
dsa
->
engine
=
e
;
return
1
;
}
int
dsa_register
(
ENGINE
*
e
)
{
if
(
!
ENGINE_set_DSA
(
e
,
&
keystore_dsa_meth
)
||
!
register_dsa_methods
())
{
ALOGE
(
"Could not set up keystore DSA methods"
);
return
0
;
}
return
1
;
}
This diff is collapsed.
Click to expand it.
keystore-engine/ecdsa_meth.cpp
deleted
100644 → 0
View file @
71251eec
/*
* Copyright 2013 The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <UniquePtr.h>
//#define LOG_NDEBUG 0
#define LOG_TAG "OpenSSL-keystore-ecdsa"
#include <cutils/log.h>
#include <binder/IServiceManager.h>
#include <keystore/IKeystoreService.h>
#include <openssl/ecdsa.h>
#include <openssl/engine.h>
// TODO replace this with real OpenSSL API when it exists
#include "crypto/ec/ec_lcl.h"
#include "crypto/ecdsa/ecs_locl.h"
#include "methods.h"
using
namespace
android
;
struct
ECDSA_SIG_Delete
{
void
operator
()(
ECDSA_SIG
*
p
)
const
{
ECDSA_SIG_free
(
p
);
}
};
typedef
UniquePtr
<
ECDSA_SIG
,
struct
ECDSA_SIG_Delete
>
Unique_ECDSA_SIG
;
static
ECDSA_SIG
*
keystore_ecdsa_do_sign
(
const
unsigned
char
*
dgst
,
int
dlen
,
const
BIGNUM
*
,
const
BIGNUM
*
,
EC_KEY
*
eckey
)
{
ALOGV
(
"keystore_ecdsa_do_sign(%p, %d, %p)"
,
dgst
,
dlen
,
eckey
);
uint8_t
*
key_id
=
reinterpret_cast
<
uint8_t
*>
(
EC_KEY_get_key_method_data
(
eckey
,
ex_data_dup
,
ex_data_free
,
ex_data_clear_free
));
if
(
key_id
==
NULL
)
{
ALOGE
(
"key had no key_id!"
);
return
0
;
}
sp
<
IServiceManager
>
sm
=
defaultServiceManager
();
sp
<
IBinder
>
binder
=
sm
->
getService
(
String16
(
"android.security.keystore"
));
sp
<
IKeystoreService
>
service
=
interface_cast
<
IKeystoreService
>
(
binder
);
if
(
service
==
NULL
)
{
ALOGE
(
"could not contact keystore"
);
return
0
;
}
int
num
=
ECDSA_size
(
eckey
);
uint8_t
*
reply
=
NULL
;
size_t
replyLen
;
int32_t
ret
=
service
->
sign
(
String16
(
reinterpret_cast
<
const
char
*>
(
key_id
)),
dgst
,
dlen
,
&
reply
,
&
replyLen
);
if
(
ret
<
0
)
{
ALOGW
(
"There was an error during dsa_do_sign: could not connect"
);
return
0
;
}
else
if
(
ret
!=
0
)
{
ALOGW
(
"Error during sign from keystore: %d"
,
ret
);
return
0
;
}
else
if
(
replyLen
<=
0
)
{
ALOGW
(
"No valid signature returned"
);
return
0
;
}
else
if
(
replyLen
>
(
size_t
)
num
)
{
ALOGW
(
"Signature is too large"
);
return
0
;
}
Unique_ECDSA_SIG
ecdsa_sig
(
d2i_ECDSA_SIG
(
NULL
,
const_cast
<
const
unsigned
char
**>
(
reinterpret_cast
<
unsigned
char
**>
(
&
reply
)),
replyLen
));
if
(
ecdsa_sig
.
get
()
==
NULL
)
{
ALOGW
(
"conversion from DER to ECDSA_SIG failed"
);
return
0
;
}
ALOGV
(
"keystore_ecdsa_do_sign(%p, %d, %p) => returning %p len %zu"
,
dgst
,
dlen
,
eckey
,
ecdsa_sig
.
get
(),
replyLen
);
return
ecdsa_sig
.
release
();
}
static
ECDSA_METHOD
keystore_ecdsa_meth
=
{
kKeystoreEngineId
,
/* name */
keystore_ecdsa_do_sign
,
/* ecdsa_do_sign */
NULL
,
/* ecdsa_sign_setup */
NULL
,
/* ecdsa_do_verify */
0
,
/* flags */
NULL
,
/* app_data */
};
static
int
register_ecdsa_methods
()
{
const
ECDSA_METHOD
*
ecdsa_meth
=
ECDSA_OpenSSL
();
keystore_ecdsa_meth
.
ecdsa_do_verify
=
ecdsa_meth
->
ecdsa_do_verify
;
return
1
;
}
int
ecdsa_pkey_setup
(
ENGINE
*
e
,
EVP_PKEY
*
pkey
,
const
char
*
key_id
)
{
Unique_EC_KEY
eckey
(
EVP_PKEY_get1_EC_KEY
(
pkey
));
void
*
oldData
=
EC_KEY_insert_key_method_data
(
eckey
.
get
(),
reinterpret_cast
<
void
*>
(
strdup
(
key_id
)),
ex_data_dup
,
ex_data_free
,
ex_data_clear_free
);
if
(
oldData
!=
NULL
)
{
free
(
oldData
);
}
ECDSA_set_method
(
eckey
.
get
(),
&
keystore_ecdsa_meth
);
/*
* "ECDSA_set_ENGINE()" should probably be an OpenSSL API. Since it isn't,
* and EC_KEY_free() calls ENGINE_finish(), we need to call ENGINE_init()
* here.
*/
ECDSA_DATA
*
ecdsa
=
ecdsa_check
(
eckey
.
get
());
ENGINE_init
(
e
);
ecdsa
->
engine
=
e
;
return
1
;
}
int
ecdsa_register
(
ENGINE
*
e
)
{
if
(
!
ENGINE_set_ECDSA
(
e
,
&
keystore_ecdsa_meth
)
||
!
register_ecdsa_methods
())
{
ALOGE
(
"Could not set up keystore ECDSA methods"
);
return
0
;
}
return
1
;
}
This diff is collapsed.
Click to expand it.
keystore-engine/eng_keystore.cpp
deleted
100644 → 0
View file @
71251eec
/*
* Copyright 2012 The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <UniquePtr.h>
#include <sys/socket.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <openssl/dsa.h>
#include <openssl/engine.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/rsa.h>
//#define LOG_NDEBUG 0
#define LOG_TAG "OpenSSL-keystore"
#include <cutils/log.h>
#include <binder/IServiceManager.h>
#include <keystore/keystore.h>
#include <keystore/IKeystoreService.h>
#include "methods.h"
using
namespace
android
;
#define DYNAMIC_ENGINE
const
char
*
kKeystoreEngineId
=
"keystore"
;
static
const
char
*
kKeystoreEngineDesc
=
"Android keystore engine"
;
/*
* ex_data index for keystore's key alias.
*/
int
rsa_key_handle
;
int
dsa_key_handle
;
/*
* Only initialize the *_key_handle once.
*/
static
pthread_once_t
key_handle_control
=
PTHREAD_ONCE_INIT
;
/**
* Many OpenSSL APIs take ownership of an argument on success but don't free the argument
* on failure. This means we need to tell our scoped pointers when we've transferred ownership,
* without triggering a warning by not using the result of release().
*/
#define OWNERSHIP_TRANSFERRED(obj) \
typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
struct
ENGINE_Delete
{
void
operator
()(
ENGINE
*
p
)
const
{
ENGINE_free
(
p
);
}
};
typedef
UniquePtr
<
ENGINE
,
ENGINE_Delete
>
Unique_ENGINE
;
struct
EVP_PKEY_Delete
{
void
operator
()(
EVP_PKEY
*
p
)
const
{
EVP_PKEY_free
(
p
);
}
};
typedef
UniquePtr
<
EVP_PKEY
,
EVP_PKEY_Delete
>
Unique_EVP_PKEY
;
/**
* Called to initialize RSA's ex_data for the key_id handle. This should
* only be called when protected by a lock.
*/
static
void
init_key_handle
()
{
rsa_key_handle
=
RSA_get_ex_new_index
(
0
,
NULL
,
keyhandle_new
,
keyhandle_dup
,
keyhandle_free
);
dsa_key_handle
=
DSA_get_ex_new_index
(
0
,
NULL
,
keyhandle_new
,
keyhandle_dup
,
keyhandle_free
);
}
static
EVP_PKEY
*
keystore_loadkey
(
ENGINE
*
e
,
const
char
*
key_id
,
UI_METHOD
*
ui_method
,
void
*
callback_data
)
{
#if LOG_NDEBUG
(
void
)
ui_method
;
(
void
)
callback_data
;
#else
ALOGV
(
"keystore_loadkey(%p,
\"
%s
\"
, %p, %p)"
,
e
,
key_id
,
ui_method
,
callback_data
);
#endif
sp
<
IServiceManager
>
sm
=
defaultServiceManager
();
sp
<
IBinder
>
binder
=
sm
->
getService
(
String16
(
"android.security.keystore"
));
sp
<
IKeystoreService
>
service
=
interface_cast
<
IKeystoreService
>
(
binder
);
if
(
service
==
NULL
)
{
ALOGE
(
"could not contact keystore"
);
return
0
;
}
uint8_t
*
pubkey
=
NULL
;
size_t
pubkeyLen
;
int32_t
ret
=
service
->
get_pubkey
(
String16
(
key_id
),
&
pubkey
,
&
pubkeyLen
);
if
(
ret
<
0
)
{
ALOGW
(
"could not contact keystore"
);
free
(
pubkey
);
return
NULL
;
}
else
if
(
ret
!=
0
)
{
ALOGW
(
"keystore reports error: %d"
,
ret
);
free
(
pubkey
);
return
NULL
;
}
const
unsigned
char
*
tmp
=
reinterpret_cast
<
const
unsigned
char
*>
(
pubkey
);
Unique_EVP_PKEY
pkey
(
d2i_PUBKEY
(
NULL
,
&
tmp
,
pubkeyLen
));
free
(
pubkey
);
if
(
pkey
.
get
()
==
NULL
)
{
ALOGW
(
"Cannot convert pubkey"
);
return
NULL
;
}
switch
(
EVP_PKEY_type
(
pkey
->
type
))
{
case
EVP_PKEY_DSA
:
{
dsa_pkey_setup
(
e
,
pkey
.
get
(),
key_id
);
break
;
}
case
EVP_PKEY_RSA
:
{
rsa_pkey_setup
(
e
,
pkey
.
get
(),
key_id
);
break
;
}
case
EVP_PKEY_EC
:
{
ecdsa_pkey_setup
(
e
,
pkey
.
get
(),
key_id
);
break
;
}
default:
ALOGE
(
"Unsupported key type %d"
,
EVP_PKEY_type
(
pkey
->
type
));
return
NULL
;
}
return
pkey
.
release
();
}
static
const
ENGINE_CMD_DEFN
keystore_cmd_defns
[]
=
{
{
0
,
NULL
,
NULL
,
0
}
};
static
int
keystore_engine_setup
(
ENGINE
*
e
)
{
ALOGV
(
"keystore_engine_setup"
);
if
(
!
ENGINE_set_id
(
e
,
kKeystoreEngineId
)
||
!
ENGINE_set_name
(
e
,
kKeystoreEngineDesc
)
||
!
ENGINE_set_load_privkey_function
(
e
,
keystore_loadkey
)
||
!
ENGINE_set_load_pubkey_function
(
e
,
keystore_loadkey
)
||
!
ENGINE_set_flags
(
e
,
0
)
||
!
ENGINE_set_cmd_defns
(
e
,
keystore_cmd_defns
))
{
ALOGE
(
"Could not set up keystore engine"
);
return
0
;
}
/* We need a handle in the keys types as well for keygen if it's not already initialized. */
pthread_once
(
&
key_handle_control
,
init_key_handle
);
if
((
rsa_key_handle
<
0
)
||
(
dsa_key_handle
<
0
))
{
ALOGE
(
"Could not set up ex_data index"
);
return
0
;
}
if
(
!
dsa_register
(
e
))
{
ALOGE
(
"DSA registration failed"
);
return
0
;
}
else
if
(
!
ecdsa_register
(
e
))
{
ALOGE
(
"ECDSA registration failed"
);
return
0
;
}
else
if
(
!
rsa_register
(
e
))
{
ALOGE
(
"RSA registration failed"
);
return
0
;
}
return
1
;
}
ENGINE
*
ENGINE_keystore
()
{
ALOGV
(
"ENGINE_keystore"
);
Unique_ENGINE
engine
(
ENGINE_new
());
if
(
engine
.
get
()
==
NULL
)
{
return
NULL
;
}
if
(
!
keystore_engine_setup
(
engine
.
get
()))
{
return
NULL
;
}
return
engine
.
release
();
}
static
int
keystore_bind_fn
(
ENGINE
*
e
,
const
char
*
id
)
{
ALOGV
(
"keystore_bind_fn"
);
if
(
!
id
)
{
return
0
;
}
if
(
strcmp
(
id
,
kKeystoreEngineId
))
{
return
0
;
}
if
(
!
keystore_engine_setup
(
e
))
{
return
0
;
}
return
1
;
}
extern
"C"
{
#undef OPENSSL_EXPORT
#define OPENSSL_EXPORT extern __attribute__ ((visibility ("default")))
IMPLEMENT_DYNAMIC_CHECK_FN
()
IMPLEMENT_DYNAMIC_BIND_FN
(
keystore_bind_fn
)
};
This diff is collapsed.
Click to expand it.
keystore-engine/keyhandle.cpp
deleted
100644 → 0
View file @
71251eec
/*
* Copyright 2012 The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <openssl/engine.h>
#include <string.h>
/**
* Makes sure the ex_data for the keyhandle is initially set to NULL.
*/
int
keyhandle_new
(
void
*
,
void
*
,
CRYPTO_EX_DATA
*
ad
,
int
idx
,
long
,
void
*
)
{
return
CRYPTO_set_ex_data
(
ad
,
idx
,
NULL
);
}
/**
* Frees a previously allocated keyhandle stored in ex_data.
*/
void
keyhandle_free
(
void
*
,
void
*
ptr
,
CRYPTO_EX_DATA
*
,
int
,
long
,
void
*
)
{
char
*
keyhandle
=
reinterpret_cast
<
char
*>
(
ptr
);
if
(
keyhandle
!=
NULL
)
{
free
(
keyhandle
);
}
}
/**
* Duplicates a keyhandle stored in ex_data in case we copy a key.
*/
int
keyhandle_dup
(
CRYPTO_EX_DATA
*
to
,
CRYPTO_EX_DATA
*
,
void
*
ptrRef
,
int
idx
,
long
,
void
*
)
{
// This appears to be a bug in OpenSSL.
void
**
ptr
=
reinterpret_cast
<
void
**>
(
ptrRef
);
char
*
keyhandle
=
reinterpret_cast
<
char
*>
(
*
ptr
);
if
(
keyhandle
!=
NULL
)
{
char
*
keyhandle_copy
=
strdup
(
keyhandle
);
*
ptr
=
keyhandle_copy
;
// Call this in case OpenSSL is fixed in the future.
(
void
)
CRYPTO_set_ex_data
(
to
,
idx
,
keyhandle_copy
);
}
return
1
;
}
void
*
ex_data_dup
(
void
*
data
)
{
char
*
keyhandle
=
reinterpret_cast
<
char
*>
(
data
);
return
strdup
(
keyhandle
);
}
void
ex_data_free
(
void
*
data
)
{
char
*
keyhandle
=
reinterpret_cast
<
char
*>
(
data
);
free
(
keyhandle
);
}
void
ex_data_clear_free
(
void
*
data
)
{
char
*
keyhandle
=
reinterpret_cast
<
char
*>
(
data
);
memset
(
data
,
'\0'
,
strlen
(
keyhandle
));
free
(
keyhandle
);
}
This diff is collapsed.
Click to expand it.
keystore-engine/rsa_meth.cpp
deleted
100644 → 0
View file @
71251eec
/*
* Copyright 2012 The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <UniquePtr.h>
//#define LOG_NDEBUG 0
#define LOG_TAG "OpenSSL-keystore-rsa"
#include <cutils/log.h>
#include <binder/IServiceManager.h>
#include <keystore/IKeystoreService.h>
#include <openssl/rsa.h>
#include <openssl/engine.h>
#include "methods.h"
using
namespace
android
;
int
keystore_rsa_priv_enc
(
int
flen
,
const
unsigned
char
*
from
,
unsigned
char
*
to
,
RSA
*
rsa
,
int
padding
)
{
ALOGV
(
"keystore_rsa_priv_enc(%d, %p, %p, %p, %d)"
,
flen
,
from
,
to
,
rsa
,
padding
);
int
num
=
RSA_size
(
rsa
);
UniquePtr
<
uint8_t
>
padded
(
new
uint8_t
[
num
]);
if
(
padded
.
get
()
==
NULL
)
{
ALOGE
(
"could not allocate padded signature"
);
return
0
;
}
switch
(
padding
)
{
case
RSA_PKCS1_PADDING
:
if
(
!
RSA_padding_add_PKCS1_type_1
(
padded
.
get
(),
num
,
from
,
flen
))
{
return
0
;
}
break
;
case
RSA_X931_PADDING
:
if
(
!
RSA_padding_add_X931
(
padded
.
get
(),
num
,
from
,
flen
))
{
return
0
;
}
break
;
case
RSA_NO_PADDING
:
if
(
!
RSA_padding_add_none
(
padded
.
get
(),
num
,
from
,
flen
))
{
return
0
;
}
break
;
default:
ALOGE
(
"Unknown padding type: %d"
,
padding
);
return
0
;
}
uint8_t
*
key_id
=
reinterpret_cast
<
uint8_t
*>
(
RSA_get_ex_data
(
rsa
,
rsa_key_handle
));
if
(
key_id
==
NULL
)
{
ALOGE
(
"key had no key_id!"
);
return
0
;
}
sp
<
IServiceManager
>
sm
=
defaultServiceManager
();
sp
<
IBinder
>
binder
=
sm
->
getService
(
String16
(
"android.security.keystore"
));
sp
<
IKeystoreService
>
service
=
interface_cast
<
IKeystoreService
>
(
binder
);
if
(
service
==
NULL
)
{
ALOGE
(
"could not contact keystore"
);
return
0
;
}
uint8_t
*
reply
=
NULL
;
size_t
replyLen
;
int32_t
ret
=
service
->
sign
(
String16
(
reinterpret_cast
<
const
char
*>
(
key_id
)),
padded
.
get
(),
num
,
&
reply
,
&
replyLen
);
if
(
ret
<
0
)
{
ALOGW
(
"There was an error during signing: could not connect"
);
free
(
reply
);
return
0
;
}
else
if
(
ret
!=
0
)
{
ALOGW
(
"Error during signing from keystore: %d"
,
ret
);
free
(
reply
);
return
0
;
}
else
if
(
replyLen
<=
0
)
{
ALOGW
(
"No valid signature returned"
);
return
0
;
}
memcpy
(
to
,
reply
,
replyLen
);
free
(
reply
);
ALOGV
(
"rsa=%p keystore_rsa_priv_enc => returning %p len %llu"
,
rsa
,
to
,
(
unsigned
long
long
)
replyLen
);
return
static_cast
<
int
>
(
replyLen
);
}
int
keystore_rsa_priv_dec
(
int
flen
,
const
unsigned
char
*
from
,
unsigned
char
*
to
,
RSA
*
rsa
,
int
padding
)
{
ALOGV
(
"keystore_rsa_priv_dec(%d, %p, %p, %p, %d)"
,
flen
,
from
,
to
,
rsa
,
padding
);
uint8_t
*
key_id
=
reinterpret_cast
<
uint8_t
*>
(
RSA_get_ex_data
(
rsa
,
rsa_key_handle
));
if
(
key_id
==
NULL
)
{
ALOGE
(
"key had no key_id!"
);
return
0
;
}
sp
<
IServiceManager
>
sm
=
defaultServiceManager
();
sp
<
IBinder
>
binder
=
sm
->
getService
(
String16
(
"android.security.keystore"
));
sp
<
IKeystoreService
>
service
=
interface_cast
<
IKeystoreService
>
(
binder
);
if
(
service
==
NULL
)
{
ALOGE
(
"could not contact keystore"
);
return
0
;
}
int
num
=
RSA_size
(
rsa
);
uint8_t
*
reply
=
NULL
;
size_t
replyLen
;
int32_t
ret
=
service
->
sign
(
String16
(
reinterpret_cast
<
const
char
*>
(
key_id
)),
from
,
flen
,
&
reply
,
&
replyLen
);
if
(
ret
<
0
)
{
ALOGW
(
"There was an error during rsa_mod_exp: could not connect"
);
return
0
;
}
else
if
(
ret
!=
0
)
{
ALOGW
(
"Error during sign from keystore: %d"
,
ret
);
return
0
;
}
else
if
(
replyLen
<=
0
)
{
ALOGW
(
"No valid signature returned"
);
return
0
;
}
/* Trim off the top zero if it's there */
uint8_t
*
alignedReply
;
if
(
*
reply
==
0x00
)
{
alignedReply
=
reply
+
1
;
replyLen
--
;
}
else
{
alignedReply
=
reply
;
}
int
outSize
;
switch
(
padding
)
{
case
RSA_PKCS1_PADDING
:
outSize
=
RSA_padding_check_PKCS1_type_2
(
to
,
num
,
alignedReply
,
replyLen
,
num
);
break
;
case
RSA_X931_PADDING
:
outSize
=
RSA_padding_check_X931
(
to
,
num
,
alignedReply
,
replyLen
,
num
);
break
;
case
RSA_NO_PADDING
:
outSize
=
RSA_padding_check_none
(
to
,
num
,
alignedReply
,
replyLen
,
num
);
break
;
default:
ALOGE
(
"Unknown padding type: %d"
,
padding
);
outSize
=
-
1
;
break
;
}
free
(
reply
);
ALOGV
(
"rsa=%p keystore_rsa_priv_dec => returning %p len %d"
,
rsa
,
to
,
outSize
);
return
outSize
;
}
static
RSA_METHOD
keystore_rsa_meth
=
{
kKeystoreEngineId
,
NULL
,
/* rsa_pub_enc (wrap) */
NULL
,
/* rsa_pub_dec (verification) */
keystore_rsa_priv_enc
,
/* rsa_priv_enc (signing) */
keystore_rsa_priv_dec
,
/* rsa_priv_dec (unwrap) */
NULL
,
/* rsa_mod_exp */
NULL
,
/* bn_mod_exp */
NULL
,
/* init */
NULL
,
/* finish */
RSA_FLAG_EXT_PKEY
|
RSA_FLAG_NO_BLINDING
,
/* flags */
NULL
,
/* app_data */
NULL
,
/* rsa_sign */
NULL
,
/* rsa_verify */
NULL
,
/* rsa_keygen */
};
static
int
register_rsa_methods
()
{
const
RSA_METHOD
*
rsa_meth
=
RSA_PKCS1_SSLeay
();
keystore_rsa_meth
.
rsa_pub_enc
=
rsa_meth
->
rsa_pub_enc
;
keystore_rsa_meth
.
rsa_pub_dec
=
rsa_meth
->
rsa_pub_dec
;
keystore_rsa_meth
.
rsa_mod_exp
=
rsa_meth
->
rsa_mod_exp
;
keystore_rsa_meth
.
bn_mod_exp
=
rsa_meth
->
bn_mod_exp
;
return
1
;
}
int
rsa_pkey_setup
(
ENGINE
*
e
,
EVP_PKEY
*
pkey
,
const
char
*
key_id
)
{
Unique_RSA
rsa
(
EVP_PKEY_get1_RSA
(
pkey
));
if
(
!
RSA_set_ex_data
(
rsa
.
get
(),
rsa_key_handle
,
reinterpret_cast
<
void
*>
(
strdup
(
key_id
))))
{
ALOGW
(
"Could not set ex_data for loaded RSA key"
);
return
0
;
}
RSA_set_method
(
rsa
.
get
(),
&
keystore_rsa_meth
);
RSA_blinding_off
(
rsa
.
get
());
/*
* "RSA_set_ENGINE()" should probably be an OpenSSL API. Since it isn't,
* and EVP_PKEY_free() calls ENGINE_finish(), we need to call ENGINE_init()
* here.
*/
ENGINE_init
(
e
);
rsa
->
engine
=
e
;
rsa
->
flags
|=
RSA_FLAG_EXT_PKEY
;
return
1
;
}
int
rsa_register
(
ENGINE
*
e
)
{
if
(
!
ENGINE_set_RSA
(
e
,
&
keystore_rsa_meth
)
||
!
register_rsa_methods
())
{
ALOGE
(
"Could not set up keystore RSA methods"
);
return
0
;
}
return
1
;
}
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment