diff options
21 files changed, 0 insertions, 2629 deletions
diff --git a/epid/Android.bp b/epid/Android.bp deleted file mode 100644 index eced70d..0000000 --- a/epid/Android.bp +++ /dev/null @@ -1,37 +0,0 @@ -cc_library { - name: "libepid", - defaults: ["epid_cflags"], - srcs: [ - "interface/*.c", - ], - export_include_dirs: [ - "interface", - ], - static_libs: [ - "libepid_verifier", - "libepid_member", - "libepid_common", - "libepid_util", - "libippcp", - ], - stl: "none", -} - -cc_test { - name: "libepid_utest", - defaults: ["epid_cflags"], - srcs: [ - "test/*.cc", - ], - static_libs: [ - "libepid", - "libepid_verifier", - "libepid_member", - "libepid_common", - "libepid_util", - "libippcp", - ], - shared_libs: [ - "libchrome", - ], -} diff --git a/epid/README.md b/epid/README.md deleted file mode 100644 index 6b30c8c..0000000 --- a/epid/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# EPID Interface Library - -The directory contains a wrapper for EPID sdk library, libepid, -which provides an easier way to create EPID signatures and verify. -The EPID sdk is located at `platform/external/epid-sdk/`. - -The C/C++ library contains two main functions `EPID_Sign` and -`EPID_Verify`. The python library include wrappers to call the -C/C++ functions, and functions to check EPID key certificate: -`verify_cert_file`. - -## Files and Dierctories - -* `interface/` - + C/C++ interface library inplementations -* `python_interface/` - + A python wrapper for the C/C++ library - + Python functions for checking EPID certificates - + Unittests for python functions -* `test/` - + Unit tests for testing EPID sign/verify funtionalities of - the C/C++ library. -* `testdata/` - + Data files used for unit tests -* `Android.bp` - + Build file used by Soong to build the library - -## Build Instructions - -The C/C++ libraries and unit tests can be built with Soong. They are -available on both the target and the host. Both shared and static -libraries are available. The build targets for the library and tests -are `libepid` and `libepid_utest`, respectively. - -C/C++ shared library `libepid.so` is needed for the python interface. -A prebuilt library for linux x86_64 is in `python_interface/` - -## `testdata/` Contents - -Unittest data include EPID public and private keys for two different -EPID groups. An EPID certificate chain (in DER format) is also incuded. -* EPID group1: - + `group1pubkey.bin`: public key binary - + `group1privkey1.bin`, `group1privkey2.bin`, `group1privkey3.bin`: - private keys -* EPID group2: - + `group2pubkey.bin`: public key binary - + `group2privkey1.bin`, `group2privkey2.bin`, `group2privkey3.bin`: - private keys -* Certificate chain: - + `cert0.cer`: certificate for the EPID key, leaf - + `cert1.cer`: intermidiate CA certificate, used to sign `cert0.cer` - + `cert2.cer`: root CA certificate, used to sign `cert0.cer`
\ No newline at end of file diff --git a/epid/interface/signmsg.c b/epid/interface/signmsg.c deleted file mode 100644 index ed63ba8..0000000 --- a/epid/interface/signmsg.c +++ /dev/null @@ -1,324 +0,0 @@ -/*############################################################################ - # Copyright 2016-2017 Intel Corporation - # - # 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. - ############################################################################ - - Original location: https://github.com/Intel-EPID-SDK/epid-sdk - Modified EPID SDK interface for Android things - -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "epid/common/src/memory.h" -#include "epid/common/stdtypes.h" -#include "epid/member/api.h" -#include "epid/member/src/context.h" -#include "epid/member/src/write_precomp.h" -#include "util/convutil.h" - -// read random numbers from /dev/urandom -int SysPrngGen(unsigned int* rand_data, int num_bits, void* user_data) { - (void)user_data; - if (num_bits <= 0) return 0; - if (num_bits % 8) return 1; - FILE* urnd = fopen("/dev/urandom", "r"); - if (urnd) { - int bytes = num_bits / 8; - size_t ret = fread(rand_data, 1, bytes, urnd); - fclose(urnd); - if (!ret) return 1; - return 0; - } else { - return 1; - } -} - -typedef struct EpidKeyATAP{ - GroupId gid; ///< group ID - ///priv key - G1ElemStr A; ///< an element in G1 - FpElemStr x; ///< an integer between [0, p-1] - FpElemStr f; ///< an integer between [0, p-1] - ///pub key - G1ElemStr h1; ///< an element in G1 - G1ElemStr h2; ///< an element in G1 - G2ElemStr w; ///< an element in G2 - -} EpidKeyATAP; - -EpidStatus EpidApiSign(void const* msg, size_t msg_len, - void const* basename, size_t basename_len, - void const* buf_privkey, size_t buf_privkey_size, - void const* buf_pubkey, size_t buf_pubkey_size, - void const* buf_sig_rl, size_t buf_sig_rl_size, - void const* buf_precomp, size_t buf_precomp_size, - HashAlg hash_alg, - EpidSignature* sig) { - EpidStatus sts = kEpidErr; - MemberCtx* member = NULL; - SigRl* sig_rl = NULL; - size_t sig_len = 360; - do { - MemberParams params = {0}; - size_t member_size = 0; - if (!sig) { - sts = kEpidBadArgErr; - break; - } - if (!buf_pubkey || buf_pubkey_size != sizeof(GroupPubKey)) { - sts = kEpidBadArgErr; - break; - } - if (!buf_privkey || buf_privkey_size != sizeof(PrivKey)) { - sts = kEpidBadArgErr; - break; - } - - MemberPrecomp const* precomp = NULL; - if (buf_precomp && buf_precomp_size == sizeof(MemberPrecomp)) { - precomp = (MemberPrecomp const*)buf_precomp; - } - - // need link RNG - params.rnd_func = &SysPrngGen; - params.rnd_param = NULL; - params.f = NULL; - - // create member - sts = EpidMemberGetSize(¶ms, &member_size); - if (kEpidNoErr != sts) { - break; - } - member = (MemberCtx*)calloc(1, member_size); - if (!member) { - sts = kEpidNoMemErr; - break; - } - sts = EpidMemberInit(¶ms, member); - if (kEpidNoErr != sts) { - break; - } - - sts = EpidMemberSetHashAlg(member, hash_alg); - if (kEpidNoErr != sts) { - break; - } - - if (buf_privkey_size == sizeof(PrivKey)) { - sts = EpidProvisionKey(member, (GroupPubKey const*)buf_pubkey, - (PrivKey const*)buf_privkey, precomp); - if (kEpidNoErr != sts) { - break; - } - } else { - sts = kEpidBadArgErr; - break; - } - - // start member - sts = EpidMemberStartup(member); - if (kEpidNoErr != sts) { - break; - } - - // register any provided basename as allowed - if (0 != basename_len) { - sts = EpidRegisterBasename(member, basename, basename_len); - if (kEpidNoErr != sts) { - break; - } - } - - // TODO the interface does not support revocation lists - // register sigRl if any - if (buf_sig_rl && buf_sig_rl_size) { - /* - // buf_sig_rl include EpidFileHeader, signature RL and EcdsaSignature - // signature is not checked - size_t min_rl_file_size = 0; - size_t empty_rl_size = 0; - size_t rl_entry_size = 0; - EpidFileHeader const* file_header = (EpidFileHeader*)buf_sig_rl; - (void)file_header; - if (!buf_sig_rl_size) { - sts = kEpidBadArgErr; - break; - } - empty_rl_size = sizeof(SigRl) - sizeof(((SigRl*)0)->bk[0]); - rl_entry_size = sizeof(((SigRl*)0)->bk[0]); - min_rl_file_size = sizeof(EpidFileHeader) + sizeof(SigRl) - - sizeof(((SigRl*)0)->bk[0]) + sizeof(EcdsaSignature); - if (min_rl_file_size > buf_sig_rl_size) return kEpidBadArgErr; - size_t sig_rl_size = buf_sig_rl_size - - sizeof(EpidFileHeader) - sizeof(EcdsaSignature); - sig_rl = calloc(1, sig_rl_size); - if (!sig_rl) { - sts = kEpidMemAllocErr; - break; - } - void const* buf_rl = buf_sig_rl + sizeof(EpidFileHeader); - if (0 != memcpy_S(sig_rl, sig_rl_size, buf_rl, sig_rl_size)) { - return kEpidBadArgErr; - } - - sts = EpidMemberSetSigRl(member, sig_rl, sig_rl_size); - if (kEpidNoErr != sts) { - break; - } - */ - } - - if (sig_len != EpidGetSigSize(sig_rl)) { - sts = kEpidMemAllocErr; - break; - } - if (!sig) { - sts = kEpidMemAllocErr; - break; - } - - // sign message - sts = EpidSign(member, msg, msg_len, basename, basename_len, sig, sig_len); - if (kEpidNoErr != sts) { - break; - } - sts = kEpidNoErr; - } while (0); // do - - EpidMemberDeinit(member); - if (member) free(member); - - if (sig_rl) free(sig_rl); - return sts; -} - -EpidStatus EpidApiSignAtap(void const* msg, size_t msg_len, - void const* basename, size_t basename_len, - void const* buf_key, size_t buf_key_size, - void const* buf_sig_rl, size_t buf_sig_rl_size, - void const* buf_precomp, size_t buf_precomp_size, - HashAlg hash_alg, - void* buf_sig, size_t* buf_sig_len) { - if (!buf_sig || !buf_sig_len) { - return kEpidBadArgErr; - } - - EpidSignature* sig = (EpidSignature*)buf_sig; - *buf_sig_len = 360; - - GroupPubKey pubkey = {0}; - PrivKey privkey = {0}; - - // get public key and private key from buf, no CA checks - if (!buf_key || buf_key_size != sizeof(EpidKeyATAP)) { - return kEpidBadArgErr; - } - EpidKeyATAP* buf_key_tmp = (EpidKeyATAP*)buf_key; - - pubkey.gid = buf_key_tmp->gid; - pubkey.h1 = buf_key_tmp->h1; - pubkey.h2 = buf_key_tmp->h2; - pubkey.w = buf_key_tmp->w; - - privkey.gid = buf_key_tmp->gid; - privkey.A = buf_key_tmp->A; - privkey.x = buf_key_tmp->x; - privkey.f = buf_key_tmp->f; - - return EpidApiSign(msg, msg_len, - basename, basename_len, - (void*) &privkey, sizeof(PrivKey), - (void*) &pubkey, sizeof(GroupPubKey), - buf_sig_rl, buf_sig_rl_size, - buf_precomp, buf_precomp_size, - hash_alg, - sig); - -} - -EpidStatus EpidApiSignPrecomp(void const* buf_key, size_t buf_key_size, - void* buf_precomp, size_t buf_precomp_size) { - EpidStatus sts = kEpidErr; - GroupPubKey pubkey = {0}; - PrivKey privkey = {0}; - MemberCtx* member = NULL; - MemberParams params = {0}; - size_t member_size = 0; - - if (!buf_precomp || buf_precomp_size != sizeof(MemberPrecomp)) { - return kEpidBadArgErr; - } - - // get public key and private key from buf, no CA checks - if (!buf_key || buf_key_size != sizeof(EpidKeyATAP)) { - return kEpidBadArgErr; - } - EpidKeyATAP* buf_key_tmp = (EpidKeyATAP*)buf_key; - - pubkey.gid = buf_key_tmp->gid; - pubkey.h1 = buf_key_tmp->h1; - pubkey.h2 = buf_key_tmp->h2; - pubkey.w = buf_key_tmp->w; - - privkey.gid = buf_key_tmp->gid; - privkey.A = buf_key_tmp->A; - privkey.x = buf_key_tmp->x; - privkey.f = buf_key_tmp->f; - - do { - // need link RNG - params.rnd_func = &SysPrngGen; - params.rnd_param = NULL; - params.f = NULL; - - // create member - sts = EpidMemberGetSize(¶ms, &member_size); - if (kEpidNoErr != sts) { - break; - } - member = (MemberCtx*)calloc(1, member_size); - if (!member) { - sts = kEpidNoMemErr; - break; - } - sts = EpidMemberInit(¶ms, member); - if (kEpidNoErr != sts) { - break; - } - - sts = EpidProvisionKey(member, &pubkey, &privkey, NULL); - if (kEpidNoErr != sts) { - break; - } - - // start member and compute precomp - sts = EpidMemberStartup(member); - if (kEpidNoErr != sts) { - break; - } - - // write precomp to buf - sts = EpidMemberWritePrecomp(member, (MemberPrecomp*)buf_precomp); - if (kEpidNoErr != sts) { - break; - } - } while (0); // do - - EpidMemberDeinit(member); - if (member) free(member); - - return kEpidNoErr; -} diff --git a/epid/interface/signmsg.h b/epid/interface/signmsg.h deleted file mode 100644 index 625196a..0000000 --- a/epid/interface/signmsg.h +++ /dev/null @@ -1,148 +0,0 @@ -/*############################################################################ - # Copyright 2016-2017 Intel Corporation - # - # 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. - ############################################################################ - - Original location: https://github.com/Intel-EPID-SDK/epid-sdk - Modified EPID SDK interface for Android things - -*/ - -#ifndef EPID_INTERFACE_SIGNMSG_H_ -#define EPID_INTERFACE_SIGNMSG_H_ - -#include "epid/common/file_parser.h" -#include "epid/member/api.h" - -#if defined __cplusplus -extern "C" { -#endif - -/* Sign message with EPID key, separate public/private keys. - * - * input: - * msg: message to sign - * msg_len: message length - * basename: basename, see documentation for details - * basename_len: basename length - * buf_privkey: private key format: (data, size(byte)) - * groupID: 16 - * A: 64 - * x: 32 - * f: 32 - * buf_privkey_size: 144 - * buf_pubkey: public key format: (data, size(byte)) - * groupID: 16 - * h1: 64 - * h2: 64 - * w: 128 - * buf_pubkey_size: 272 or longer, excess are discarded - * buf_sig_rl: signature revocation list - * buf_sig_rl_size: signature revocation list size - * buf_precomp: memory for precomp, no use if NULL - * precomp_size: 1552 - * hash_algo: digest sha-256 ->0; sha-512->2 - * - * output: - * sig: signature - * - * return: - * EpidStatus: 0->signed, others->error - */ -EpidStatus EpidApiSign(void const* msg, - size_t msg_len, - void const* basename, - size_t basename_len, - void const* buf_privkey, - size_t buf_privkey_size, - void const* buf_pubkey, - size_t buf_pubkey_size, - void const* buf_sig_rl, - size_t buf_sig_rl_size, - void const* buf_precomp, - size_t buf_precomp_size, - HashAlg hash_alg, - EpidSignature* sig); - -/* Sign message with EPID key, bundled public and private keys. - * - * input: - * msg: message to sign - * msg_len: message length - * basename: basename, see documentation for details - * basename_len: basename length - * buf_key: bundled private and public key format: (data, size(byte)) - * groupID: 16 - * A: 64 - * x: 32 - * f: 32 - * h1: 64 - * h2: 64 - * w: 128 - * buf_pubkey_size: 400 or longer, excess are discarded - * buf_sig_rl: signature revocation list - * buf_sig_rl_size: signature revocation list size - * buf_precomp: memory for precomp, no use if NULL - * precomp_size: 1552 - * hash_algo: digest sha-256 ->0; sha-512->2 - * - * output: - * buf_sig: allocated memory for signature - * sig_len: >=360 - * - * return: - * EpidStatus: 0->signed, others->error - */ -EpidStatus EpidApiSignAtap(void const* msg, - size_t msg_len, - void const* basename, - size_t basename_len, - void const* buf_key, - size_t buf_key_size, - void const* buf_sig_rl, - size_t buf_sig_rl_size, - void const* buf_precomp, - size_t buf_precomp_size, - HashAlg hash_alg, - void* buf_sig, - size_t* sig_len); - -/* create precompute blob to accelerate later signing. - * - * input: - * buf_key: bundled private and public key format: (data, size(byte)) - * groupID: 16 - * A: 64 - * x: 32 - * f: 32 - * h1: 64 - * h2: 64 - * w: 128 - * buf_pubkey_size: 400 or longer, excess are discarded - * - * output: - * buf_precomp: allocated memory for precomp - * precomp_size: 1536 - * - * return: - * EpidStatus: 0->signed, others->error - */ -EpidStatus EpidApiSignPrecomp(void const* buf_key, - size_t buf_key_size, - void* buf_precomp, - size_t buf_size); -#if defined __cplusplus -} -#endif // defined __cplusplus -#endif // EPID_INTERFACE_SIGNMSG_H_ diff --git a/epid/interface/verifysig.c b/epid/interface/verifysig.c deleted file mode 100644 index 0abf9db..0000000 --- a/epid/interface/verifysig.c +++ /dev/null @@ -1,234 +0,0 @@ -/*############################################################################ - # Copyright 2016-2017 Intel Corporation - # - # 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. - ############################################################################ - - Original location: https://github.com/Intel-EPID-SDK/epid-sdk - Modified EPID SDK interface for Android things - -*/ - -#include <stdlib.h> -#include "epid/verifier/api.h" - -EpidStatus EpidApiVerify(void const* sig, size_t sig_len, - void const* msg,size_t msg_len, - void const* basename, size_t basename_len, - void const* signed_priv_rl, - size_t signed_priv_rl_size, - void const* signed_sig_rl, size_t signed_sig_rl_size, - void const* signed_grp_rl, size_t signed_grp_rl_size, - VerifierRl const* ver_rl, size_t ver_rl_size, - void const* buf_pubkey, size_t buf_pubkey_size, - void const* buf_precomp, size_t buf_precomp_size, - HashAlg hash_alg) { - EpidStatus result = kEpidErr; - VerifierCtx* ctx = NULL; - PrivRl* priv_rl = NULL; - SigRl* sig_rl = NULL; - GroupRl* grp_rl = NULL; - - do { - if (!buf_pubkey || buf_pubkey_size != sizeof(GroupPubKey)) { - result = kEpidBadArgErr; - break; - } - - VerifierPrecomp const* precomp = NULL; - if (buf_precomp && buf_precomp_size == sizeof(VerifierPrecomp)) { - precomp = (VerifierPrecomp const*)buf_precomp; - } - - // create verifier - result = EpidVerifierCreate((GroupPubKey const*)buf_pubkey, precomp, &ctx); - if (kEpidNoErr != result) { - break; - } - /* - // serialize verifier pre-computation blob - if (!*verifier_precomp) { - *verifier_precomp = calloc(1, *verifier_precomp_size); - } - result = EpidVerifierWritePrecomp(ctx, *verifier_precomp); - if (kEpidNoErr != result) { - break; - } - */ - // set hash algorithm used for signing - result = EpidVerifierSetHashAlg(ctx, hash_alg); - if (kEpidNoErr != result) { - break; - } - - // set the basename used for signing - result = EpidVerifierSetBasename(ctx, basename, basename_len); - if (kEpidNoErr != result) { - break; - } - - if (signed_priv_rl && signed_priv_rl_size) { - // TODO enable private key RL - /* - // authenticate and determine space needed for RL - size_t priv_rl_size = 0; - result = EpidParsePrivRlFile(signed_priv_rl, signed_priv_rl_size, cacert, - NULL, &priv_rl_size); - if (kEpidNoErr != result) { - break; - } - - priv_rl = calloc(1, priv_rl_size); - if (!priv_rl) { - result = kEpidMemAllocErr; - break; - } - - // fill the rl - result = EpidParsePrivRlFile(signed_priv_rl, signed_priv_rl_size, cacert, - priv_rl, &priv_rl_size); - if (kEpidNoErr != result) { - break; - } - - // set private key based revocation list - result = EpidVerifierSetPrivRl(ctx, priv_rl, priv_rl_size); - if (kEpidNoErr != result) { - break; - }*/ - } // if (signed_priv_rl) - - if (signed_sig_rl && signed_sig_rl_size) { - // no need to enable signature RL - /* - // authenticate and determine space needed for RL - size_t sig_rl_size = 0; - result = EpidParseSigRlFile(signed_sig_rl, signed_sig_rl_size, cacert, - NULL, &sig_rl_size); - if (kEpidNoErr != result) { - break; - } - - sig_rl = calloc(1, sig_rl_size); - if (!sig_rl) { - result = kEpidMemAllocErr; - break; - } - - // fill the rl - result = EpidParseSigRlFile(signed_sig_rl, signed_sig_rl_size, cacert, - sig_rl, &sig_rl_size); - if (kEpidNoErr != result) { - break; - } - - // set signature based revocation list - result = EpidVerifierSetSigRl(ctx, sig_rl, sig_rl_size); - if (kEpidNoErr != result) { - break; - } - */ - } // if (signed_sig_rl) - - if (signed_grp_rl && signed_grp_rl_size) { - // TODO enable public key RL - /* - // authenticate and determine space needed for RL - size_t grp_rl_size = 0; - result = EpidParseGroupRlFile(signed_grp_rl, signed_grp_rl_size, cacert, - NULL, &grp_rl_size); - if (kEpidNoErr != result) { - break; - } - - grp_rl = calloc(1, grp_rl_size); - if (!grp_rl) { - result = kEpidMemAllocErr; - break; - } - - // fill the rl - result = EpidParseGroupRlFile(signed_grp_rl, signed_grp_rl_size, cacert, - grp_rl, &grp_rl_size); - if (kEpidNoErr != result) { - break; - } - // set group revocation list - result = EpidVerifierSetGroupRl(ctx, grp_rl, grp_rl_size); - if (kEpidNoErr != result) { - break; - } - */ - } // if (signed_grp_rl) - - if (ver_rl && ver_rl_size) { - //no need to enable verifier RL - /* - // set verifier based revocation list - result = EpidVerifierSetVerifierRl(ctx, ver_rl, ver_rl_size); - if (kEpidNoErr != result) { - break; - } - */ - } - - // verify signature - result = EpidVerify(ctx, sig, sig_len, msg, msg_len); - if (kEpidNoErr != result) { - break; - } - } while (0); // do - - // delete verifier - EpidVerifierDelete(&ctx); - - if (priv_rl) free(priv_rl); - if (sig_rl) free(sig_rl); - if (grp_rl) free(grp_rl); - - return result; -} - -EpidStatus EpidApiVerifyPrecomp(void const* buf_key, size_t buf_key_size, - void* buf_precomp, size_t buf_size) { - EpidStatus result = kEpidErr; - VerifierCtx* ctx = NULL; - - do { - if (!buf_key || buf_key_size != sizeof(GroupPubKey)) { - result = kEpidBadArgErr; - break; - } - if (!buf_precomp || buf_size != sizeof(VerifierPrecomp)) { - result = kEpidBadArgErr; - break; - } - - // create verifier and precompute - result = EpidVerifierCreate((GroupPubKey const*)buf_key, NULL, &ctx); - if (kEpidNoErr != result) { - break; - } - - // write precomp to buf - result = EpidVerifierWritePrecomp(ctx, (VerifierPrecomp*)buf_precomp); - if (kEpidNoErr != result) { - break; - } - - } while(0); // do - - // delete verifier - EpidVerifierDelete(&ctx); - return result; -} diff --git a/epid/interface/verifysig.h b/epid/interface/verifysig.h deleted file mode 100644 index 7909d73..0000000 --- a/epid/interface/verifysig.h +++ /dev/null @@ -1,104 +0,0 @@ -/*############################################################################ - # Copyright 2016-2017 Intel Corporation - # - # 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. - ############################################################################ - - Original location: https://github.com/Intel-EPID-SDK/epid-sdk - Modified EPID SDK interface for Android things - -*/ - -#ifndef EPID_INTERFACE_VERIFYSIG_H_ -#define EPID_INTERFACE_VERIFYSIG_H_ - -#include <stddef.h> -#include "epid/common/errors.h" -#include "epid/common/stdtypes.h" -#include "epid/common/types.h" - -#if defined __cplusplus -extern "C" { -#endif - -/* Verify EPID signature - * - * input: - * sig: signature to check - * sig_len: signature length - * msg: message to sign - * msg_len: message length - * basename: basename, see documentation for details - * basename_len: basename length - * - * *rl: revocation lists - * - * buf_pubkey: public key format: (data, size(byte)) - * groupID: 16 - * h1: 64 - * h2: 64 - * w: 128 - * buf_pubkey_size: 272 or longer, excess are discarded - * buf_precomp: precomp blob - * precomp_size: 1552 - * hash_algo: digest sha-256 ->0; sha-512->2 - * - * return: - * EpidStatus 0->verified; others->not - */ -EpidStatus EpidApiVerify(void const* sig, - size_t sig_len, - void const* msg, - size_t msg_len, - void const* basename, - size_t basename_len, - void const* signed_priv_rl, - size_t signed_priv_rl_size, - void const* signed_sig_rl, - size_t signed_sig_rl_size, - void const* signed_grp_rl, - size_t signed_grp_rl_size, - VerifierRl const* ver_rl, - size_t ver_rl_size, - void const* buf_pubkey, - size_t buf_pubkey_size, - void const* buf_precomp, - size_t buf_precomp_size, - HashAlg hash_alg); - -/* created precompute blob to accelerate later verifications - * of the same EPID group. - * - * input: - * buf_pubkey: public key format: (data, size(byte)) - * groupID: 16 - * h1: 64 - * h2: 64 - * w: 128 - * buf_pubkey_size: 272 or longer, excess are discarded - * - * output: - * buf_precomp: allocated memory for precomp - * precomp_size: 1536 - * - * return: - * EpidStatus 0->success; others->not - */ -EpidStatus EpidApiVerifyPrecomp(void const* buf_key, - size_t buf_key_size, - void* buf_precomp, - size_t buf_size); -#if defined __cplusplus -} -#endif // defined __cplusplus -#endif // EPID_INTERFACE_VERIFYSIG_H_ diff --git a/epid/python_interface/epid_interface.py b/epid/python_interface/epid_interface.py deleted file mode 100644 index b560106..0000000 --- a/epid/python_interface/epid_interface.py +++ /dev/null @@ -1,732 +0,0 @@ -# -# Copyright 2018 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. -# - -"""python utility functions for EPID. - - 1. sign a message - 2. verify a signature - 3. verify a EPID key certificate -""" - -from ctypes import c_int -from ctypes import c_size_t -from ctypes import c_ubyte -from ctypes import cdll -from ctypes import create_string_buffer -from ctypes import POINTER -import datetime -import hashlib -import os -from pyasn1.codec.der import decoder -from pyasn1_modules import rfc5280 -from pyasn1.type.error import PyAsn1Error -from pyasn1.type import namedtype -from pyasn1.type import univ -import sh - -# EPID signature size without signature RL -EPID_SIG_SIZE = 360 -# 256bit ECC curve byte size is 32 -_EPID_COORD_LEN = 32 -# EPID group ID length is 16 bytes -_EPID_GID_LEN = 16 - -# EPID private key group ID -_EPID_GID_START = 14 -_EPID_GID_END = 30 -# EPID private key Key location -_EPID_KEY_START = 30 -_EPID_KEY_END = 158 -# EPID private key sha-1 hash location -_EPID_SHA1_START = 158 -_EPID_SHA1_END = 178 - -# hash algorithms -_HASH_ALGOS = { - 'SHA-256': 0, - 'SHA-384': 1, - 'SHA-512': 2, - 'SHA-512_256': 3, - 'SHA3_256': 4, - 'SHA3_384': 5, - 'SHA3_512': 6, -} - - -_HASH_ALGOS_ALT = { - '-sha256': 0, - '-sha512': 2, -} - - -def read_file(filename): - try: - with open(filename, 'rb') as f: - buf = f.read() - except IOError: - buf = '' - return buf - - -def convertHashAlg(hashalgo): - """Convert hash algo string into an int recognized by EPID SDK. - - Currently only SHA256 and SHA512 is recognized. - - Args: - hashalgo: a string, must be in _HASH_ALGOS or _HASH_ALGOS_ALT - Return: - int: enum defined by EPID SDK, see _HAHS_ALGOS - Raises: - RuntimeError: Unsupported hash function - """ - if hashalgo in _HASH_ALGOS.keys(): - return c_int(_HASH_ALGOS[hashalgo]) - elif hashalgo in _HASH_ALGOS_ALT.keys(): - return c_int(_HASH_ALGOS_ALT[hashalgo]) - else: - raise RuntimeError('Unsupported hash function') - - -def signmsg(privkey, pubkey, msg, hashalgo='SHA-512'): - """Create signature with EPID key. - - Args: - privkey: size must be 144; format: (data, size(byte)) - groupID 16 - A 64 - x 32 - f 32 - pubkey: size must be 144; format: (data, size(byte)) - groupID 16 - h1 64 - h2 64 - w 128 - msg: message to sign - hashalgo: supported option see: _HASH_ALGOS, _HASH_ALGO_ALT - - Returns: - signature: size=360 - - Raises: - RuntimeError: - """ - # digest algorithm - try: - hashalg = convertHashAlg(hashalgo) - except RuntimeError as e: - raise e - - # create buffer to store signature - sig = (c_ubyte * EPID_SIG_SIZE).from_buffer(bytearray(EPID_SIG_SIZE)) - sig_p = POINTER(c_ubyte)(sig) - - helper = cdll.LoadLibrary('./libepid.so') - sign = helper.EpidApiSign - sign.argtypes = [ - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - c_int, - POINTER(c_ubyte) - ] - - status = sign( - POINTER(c_ubyte)(create_string_buffer(msg)), len(msg), - None, 0, - POINTER(c_ubyte)(create_string_buffer(privkey)), len(privkey), - POINTER(c_ubyte)(create_string_buffer(pubkey)), len(pubkey), - None, 0, - None, 0, - hashalg, - sig_p - ) - - if status: - raise RuntimeError('signature failed: ', status) - return bytes(bytearray(sig[0:360])) - - -def signmsg_atap(key, msg, hashalgo='SHA-512'): - """Create signature with EPID key. - - Args: - key: size must be 400; format: (data, size(byte)) - groupID 16 - A 64 - x 32 - f 32 - h1 64 - h2 64 - w 128 - msg: message to sign - hashalgo: supported option see: _HASH_ALGOS - 'SHA-256' - 'SHA-512' - - Returns: - signature: size=360 - - Raises: - RuntimeError: Errors while signing - """ - # digest algorithm - try: - hashalg = convertHashAlg(hashalgo) - except RuntimeError as e: - raise e - - # create buffer to store signature - sig = (c_ubyte * EPID_SIG_SIZE).from_buffer(bytearray(EPID_SIG_SIZE)) - sig_p = POINTER(c_ubyte)(sig) - sig_len = c_size_t() - sig_len_p = POINTER(c_size_t)(sig_len) - - helper = cdll.LoadLibrary('./libepid.so') - sign = helper.EpidApiSignAtap - sign.argtypes = [ - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - c_int, - POINTER(c_ubyte), POINTER(c_size_t) - ] - - status = sign( - POINTER(c_ubyte)(create_string_buffer(msg)), len(msg), - None, 0, - POINTER(c_ubyte)(create_string_buffer(key)), len(key), - None, 0, - None, 0, - hashalg, - sig_p, sig_len_p - ) - - if status: - raise RuntimeError('signature failed: ', status) - return bytes(bytearray(sig[0:360])) - - -def verifysig(sig, msg, pubkey, hashalgo='SHA-512'): - """Verify EPID key signature. - - Args: - sig: signature - msg: message to sign - pubkey: size must be 144; format: (data, size(byte)) - groupID 16 - h1 64 - h2 64 - w 128 - hashalgo: supported option see: _HASH_ALGOS - - Returns: - Boolean: True->verified, False->not verified - """ - # digest algorithm - try: - hashalg = convertHashAlg(hashalgo) - except RuntimeError: - return False - - helper = cdll.LoadLibrary('./libepid.so') - verify = helper.EpidApiVerify - verify.argtypes = [ - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - POINTER(c_ubyte), c_size_t, - c_int - ] - - status = verify( - POINTER(c_ubyte)(create_string_buffer(sig)), len(sig), - POINTER(c_ubyte)(create_string_buffer(msg)), len(msg), - None, 0, - None, 0, - None, 0, - None, 0, - None, 0, - POINTER(c_ubyte)(create_string_buffer(pubkey)), len(pubkey), - None, 0, - hashalg - ) - - return status == 0 - - -def extract_private_key(buf): - """Extract EPID private key from Intel format. - - Args: - buf: buffer to read the file; format:(data, size(byte)) - productID 2 - key ID 8 - Security ver. 4 - group ID 16 - private key 128 - SHA1 of above 20 - Returns: - private key: size = 144; format: (data, size(byte)) - groupID 16 - A 64 - x 32 - f 32 - Raises: - RuntimeError: - """ - # read key file - if len(buf) != _EPID_SHA1_END: - raise RuntimeError('Private key format error') - # check hash value correct - h = hashlib.new('sha1') - h.update(buf[:_EPID_KEY_END]) - if h.digest() != buf[_EPID_SHA1_START:_EPID_SHA1_END]: - raise RuntimeError('Private key format error') - - return buf[_EPID_GID_START:_EPID_KEY_END] - - -# ASN.1 schema object for pyasn1 -class EpidGroupPublicKey(univ.Sequence): - pass - - -EpidGroupPublicKey.componentType = namedtype.NamedTypes( - namedtype.NamedType('gid', univ.Integer()), - namedtype.NamedType('h1', univ.OctetString()), - namedtype.NamedType('h2', univ.OctetString()), - namedtype.NamedType('w', univ.OctetString()), -) - - -def extract_public_key(buf): - """Extract EPID public Key from certificate. - - Args: - buf: buffer containing EPID public key certificate DER format - - Returns: - public key: size = 144; format: (data, size(byte)) - groupID 16 - h1 64 - h2 64 - w 128 - Raises: - RuntimeError: - """ - try: - cert = decoder.decode(buf, asn1Spec=rfc5280.Certificate())[0] - except PyAsn1Error: - raise RuntimeError('public key format error') - - try: - ret = extract_public_key_from_cert(cert) - except RuntimeError as e: - raise e - return ret - - -def extract_public_key_from_cert(cert): - """Extract EPID public Key from certificate. - - Args: - cert: PyAsn1 Certificate object - - Returns: - public key: size = 144; format: (data, size(byte)) - groupID 16 - h1 64 - h2 64 - w 128 - Raises: - RuntimeError: - """ - - try: - pkey = decoder.decode(cert['tbsCertificate']['subjectPublicKeyInfo'][1]. - asOctets(), asn1Spec=EpidGroupPublicKey())[0] - except PyAsn1Error: - raise RuntimeError('public key format error') - - gid = int(pkey['gid']) - gid_str = '' - - while gid: - gid_str = chr(gid & 255) + gid_str - gid >>= 8 - - if len(gid_str) > _EPID_GID_LEN: - raise RuntimeError('public key format error') - gid_str = gid_str.rjust(_EPID_GID_LEN, chr(0)) - - # strip 0x04 char from each entry h1, h2, w - h1 = pkey['h1'].asOctets()[1:] - if len(h1) != _EPID_COORD_LEN * 2: - raise RuntimeError('public key format error') - - h2 = pkey['h2'].asOctets()[1:] - if len(h2) != _EPID_COORD_LEN * 2: - raise RuntimeError('public key format error') - - w = pkey['w'].asOctets()[1:] - if len(w) != _EPID_COORD_LEN * 4: - raise RuntimeError('public key format error') - - return gid_str + h1 + h2 + w - - -def extract_dgst(buf): - """Extract dgst algorithm from certificate file buffer. - - certificate must be a DER format. - - Args: - buf: certificate file buffer - - Returns: - string: algorithm option string '-sha512' '-sha256' - - Raises: - RuntimeError: - """ - try: - cert = decoder.decode(buf, asn1Spec=rfc5280.Certificate())[0] - oid = str(cert['tbsCertificate']['subjectPublicKeyInfo'] - ['algorithm']['algorithm']) - except PyAsn1Error: - raise RuntimeError('certificate format error') - - return extract_dgst_oid(oid) - - -def extract_dgst_oid(oid): - """Extract dgst algorithm from an object identifier. - - Support algos are sha256 and sha512 only. - - Args: - oid: a string contatining dgst algo string - Return: - dgst flag string '-sha256' or '-sha512'. EPID uses -sha256 - Raises: - RuntimeError - """ - if oid == '1.2.840.10045.4.3.4': - return '-sha512' - elif oid in ['1.2.840.10045.4.3.2', '1.2.840.113741.1.9.4.3']: - return '-sha256' - else: - raise RuntimeError('dgst algorithm not supported') - - -def _remove_tmp_files(tmp_files): - for tmp_file in tmp_files: - try: - os.remove(tmp_file) - except OSError: - pass - - -def verify_cert_file(cert_f, cacert_f): - """Verify certificate in cert_f is signed by cacert_f. - - cert_f may be an EPID key. - cacert_f may not be an EPID key. - - Args: - cert_f: certificate file to be checked DER format. - cacert_f: CA certificate file DER format. - - Returns: - String: 'OKAY' -> success, 'FAIL' + error message -> failure - - Exceptions: - None - """ - cert_type = rfc5280.Certificate() - - # temporary files - ca_pubkey_f = 'ca_pubkey.pem' - tbs_cert_f = 'tbs_certificate.bin' - sig_f = 'signature.bin' - - tmp_files = [ca_pubkey_f, tbs_cert_f, sig_f] - - # extract tbs certificate - try: - parsed = sh.openssl('asn1parse', '-inform', - 'DER', '-in', cert_f).splitlines() - except sh.ErrorReturnCode as e: - _remove_tmp_files(tmp_files) - return 'FAIL openssl unable to read certificate' + e.message - - split = str(parsed[1]).replace('=', ' ').replace(':', ' ').split() - - tbs_cert_begin = int(split[0]) - tbs_cert_len = int(split[4]) + int(split[6]) - - try: - sh.dd('if='+cert_f, 'of='+tbs_cert_f, 'skip='+str(tbs_cert_begin), 'bs=1', - 'count='+str(tbs_cert_len)) - except sh.ErrorReturnCode as e: - _remove_tmp_files(tmp_files) - return 'FAIL failed to extract tbs certificate ' + e.message - - # extract signature from certificate - # parse certificate - try: - cert = decoder.decode(read_file(cert_f), asn1Spec=cert_type)[0] - except PyAsn1Error: - _remove_tmp_files(tmp_files) - return 'FAIL certificate parsing error' - sig = cert['signature'].asOctets() - - # signature algo - try: - dgst_algo = extract_dgst_oid(str(cert['signatureAlgorithm']['algorithm'])) - except: - _remove_tmp_files(tmp_files) - return 'FAIL dgst algorithm not supported' - - # write signature to binary file - try: - with open(sig_f, 'wb') as f: - f.write(sig) - except IOError: - _remove_tmp_files(tmp_files) - return 'FAIL cannot wrtie to signature file' - - # get CA public key - try: - sh.openssl('x509', '-inform', 'DER', '-in', cacert_f, '-pubkey', - '-noout', '-out', ca_pubkey_f) - except sh.ErrorReturnCode as e: - _remove_tmp_files(tmp_files) - return 'FAIL CA certificate parsing error ' + e.message - - # check signature - try: - sh.openssl('dgst', dgst_algo, '-verify', ca_pubkey_f, - '-signature', sig_f, tbs_cert_f) - except sh.ErrorReturnCode as e: - _remove_tmp_files(tmp_files) - return 'FAIL signature check failed ' + e.message - - # parse CA certificate - try: - cacert = decoder.decode(read_file(cacert_f), asn1Spec=cert_type)[0] - except PyAsn1Error: - _remove_tmp_files(tmp_files) - return 'FAIL CA certificate parsing error' - - # verify contents of cert files, including extensions. - _remove_tmp_files(tmp_files) - - # check issuer in cert and subject in cacert match - if cert['tbsCertificate']['issuer'] != cacert['tbsCertificate']['subject']: - return 'FAIL certificate Issuer and CA certificate Subject do no match' - - res = verify_cert_validity(cert['tbsCertificate']['validity']) - if res != 'OKAY': - return res - - res = verify_cert_exts(cert['tbsCertificate']['extensions'],\ - cacert['tbsCertificate']['extensions']) - if res != 'OKAY': - return res - return 'OKAY' - - -def verify_cert_validity(validity): - """Verify a Validity object of a cert is currently valid. - - Input can be from any certificate. It may be an EPID key. - - Args: - validity: rfc5280 Validity type defined in pyasn1_modules - - Returns: - String: 'OKAY' -> success, 'FAIL' + error message -> failure - - Exceptions: - None - """ - - # check certificate validity - time_type = validity[0].getName() - if validity[1].getName() != time_type: - return 'FAIL certificate time format error' - if time_type != 'utcTime': - return 'FAIL certificate time format error' - - time_start = validity[0][time_type].asDateTime - time_start = time_start.replace(tzinfo=None) - time_now = datetime.datetime.utcnow() - - if (time_now - time_start).total_seconds() < 0: - return 'FAIL certificate not valid yet' - - time_end = validity[1][time_type].asDateTime - time_end = time_end.replace(tzinfo=None) - - if (time_end - time_now).total_seconds() < 0: - return 'FAIL certificate expired' - - return 'OKAY' - - -def verify_cert_exts(cert_exts, cacert_exts): - """Verify the extensions of certificates cert_exts and cacert_exts. - - cert_exts is the extension of a certificate cert. - cacert_exts is the extension of a certificate cacert. - The key of cacert is used to sign cert. - The checks include key usage, basic constraints and key identifiers. - - Args: - cert: rfc5280 Extensions type defined in pyasn1_modules - cacert: rfc5280 Extensions type defined in pyasn1_modules - - Returns: - String: 'OKAY' -> success, 'FAIL' + error message -> failure - - Exceptions: - None - """ - cert_ext_map = rfc5280.certificateExtensionsMap - - # parse certificate extensions - cert_ca_key_id = '' - cert_bc_ca = False - cert_bc_pathlen = -1 - # cert_keyusage_ca = -1 - # cert_keyusage_crl = -1 - - for i in range(len(cert_exts)): - extn_id = cert_exts[i]['extnID'] - if extn_id not in cert_ext_map.keys(): - return 'FAIL certificate unrecognized extension' - - if extn_id == rfc5280.id_ce_keyUsage: - # keyUsage - # check CA CRL capability only - try: - key_usage = decoder.decode(cert_exts[i]['extnValue'].asOctets(), - asn1Spec=cert_ext_map[extn_id])[0] - except PyAsn1Error: - return 'FAIL keyUsage parsing error' - # cert_keyusage_ca = key_usage[key_usage.namedValues['keyCertSign']] - # cert_keyusage_crl = key_usage[key_usage.namedValues['cRLSign']] - elif extn_id == rfc5280.id_ce_authorityKeyIdentifier: - # authorityKeyIdentifier - try: - auth_key_id = decoder.decode(cert_exts[i]['extnValue'].asOctets(), - asn1Spec=cert_ext_map[extn_id])[0] - except PyAsn1Error: - return 'FAIL authorityKeyIdentifier parsing error' - if len(auth_key_id) < 1 or len(auth_key_id) > 3: - return 'FAIL authorityKeyIdentifier parsing error' - cert_ca_key_id = str(auth_key_id[0].asOctets()) - elif extn_id == rfc5280.id_ce_basicConstraints: - # basicConstraints - try: - bc = decoder.decode(cert_exts[i]['extnValue'].asOctets(), - asn1Spec=cert_ext_map[extn_id])[0] - except PyAsn1Error: - return 'FAIL basicConstraints parsing error' - if len(bc) == 1: - cert_bc_ca = bool(bc[0]) - elif len(bc) == 2: - cert_bc_ca = bool(bc[0]) - cert_bc_pathlen = int(bc[1]) - else: - return 'FAIL basicConstraints parsing error' - - # parsing CA certificate extensions - cacert_key_id = '' - cacert_bc_ca = False - cacert_bc_pathlen = -1 - cacert_keyusage_ca = -1 - # cacert_keyusage_crl = -1 - - for i in range(len(cacert_exts)): - extn_id = cacert_exts[i]['extnID'] - if extn_id not in cert_ext_map.keys(): - return 'FAIL CA certificate unrecognized extension' - - if extn_id == rfc5280.id_ce_keyUsage: - # keyUsage - # check CA CRL capability only - try: - key_usage = decoder.decode(cacert_exts[i]['extnValue'].asOctets(), - asn1Spec=cert_ext_map[extn_id])[0] - except PyAsn1Error: - return 'FAIL CA keyUsage parsing error' - cacert_keyusage_ca = key_usage[key_usage.namedValues['keyCertSign']] - # cacert_keyusage_crl = key_usage[key_usage.namedValues['cRLSign']] - elif extn_id == rfc5280.id_ce_subjectKeyIdentifier: - # subjectKeyIdentifier - try: - subject_key_id = decoder.decode(cacert_exts[i]['extnValue'].asOctets(), - asn1Spec=cert_ext_map[extn_id])[0] - except PyAsn1Error: - return 'FAIL subjectKeyIdentifier parsing error' - cacert_key_id = str(subject_key_id.asOctets()) - elif extn_id == rfc5280.id_ce_basicConstraints: - # basicConstraints - try: - bc = decoder.decode(cacert_exts[i]['extnValue'].asOctets(), - asn1Spec=cert_ext_map[extn_id])[0] - except PyAsn1Error: - return 'FAIL CA basicConstraints parsing error' - if len(bc) == 1: - cacert_bc_ca = bool(bc[0]) - elif len(bc) == 2: - cacert_bc_ca = bool(bc[0]) - cacert_bc_pathlen = int(bc[1]) - else: - return 'FAIL CA basicConstraints parsing error' - - if cert_ca_key_id and cacert_key_id and cert_ca_key_id != cacert_key_id: - return 'FAIL key Identifiers mismatch' + cert_ca_key_id + cacert_key_id - - if (cacert_bc_ca and cacert_keyusage_ca == 0) or \ - (not cacert_bc_ca and cacert_keyusage_ca == 1): - return 'FAIL contradicting CA capablity' - - if not cacert_bc_ca: - return 'FAIL signer is not capable of signing certificate' - - if cacert_bc_ca and cacert_bc_pathlen == 0 and cert_bc_ca: - return 'FAIL signer is not capable of authorizing CA' - - if cacert_bc_pathlen > -1 and cert_bc_ca and \ - (cert_bc_pathlen == -1 or cert_bc_pathlen >= cacert_bc_pathlen): - return 'FAIL certificate pathlen is not permissible' - - # all checks pass, return 'OKAY' - return 'OKAY' diff --git a/epid/python_interface/epid_interface_unittest.py b/epid/python_interface/epid_interface_unittest.py deleted file mode 100644 index 1061be2..0000000 --- a/epid/python_interface/epid_interface_unittest.py +++ /dev/null @@ -1,343 +0,0 @@ -# -# Copyright 2018 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. -# - -"""Tests for epid_interface.py. - -Tests include EPID signature/verification and EPID certificate check. -""" - -import datetime -import epid_interface -import hashlib -from pyasn1.codec.der import decoder -from pyasn1.codec.der import encoder -from pyasn1_modules import rfc5280 -from pyasn1.type.univ import ObjectIdentifier -from pyasn1.type.univ import tag -import sh -import unittest - -class EpidSignatureTest(unittest.TestCase): - g1pubkey = epid_interface.read_file('../testdata/group1pubkey.bin') - g1privkey1 = epid_interface.read_file('../testdata/group1privkey1.bin') - g1privkey2 = epid_interface.read_file('../testdata/group1privkey2.bin') - g1privkey3 = epid_interface.read_file('../testdata/group1privkey3.bin') - g2pubkey = epid_interface.read_file('../testdata/group2pubkey.bin') - g2privkey1 = epid_interface.read_file('../testdata/group2privkey1.bin') - g2privkey2 = epid_interface.read_file('../testdata/group2privkey2.bin') - g2privkey3 = epid_interface.read_file('../testdata/group2privkey3.bin') - - # test sign and verify - def testSignVerify1(self): - msg = 'test message' - sig = epid_interface.signmsg_atap(self.g1privkey1, msg) - self.assertTrue(epid_interface.verifysig(sig, msg, self.g1pubkey)) - - def testSignVerify2(self): - msg = 'test message' - sig = epid_interface.signmsg_atap(self.g1privkey1, msg) - self.assertFalse(epid_interface.verifysig(sig, msg, self.g2pubkey)) - - def testSignVerify3(self): - msg1 = 'test message1' - msg2 = 'test message2' - sig = epid_interface.signmsg_atap(self.g1privkey1, msg1) - self.assertFalse(epid_interface.verifysig(sig, msg2, self.g2pubkey)) - - def testSignVerify4(self): - msg = 'test message' - sig = epid_interface.signmsg_atap(self.g1privkey1, msg, '-sha256') - self.assertFalse(epid_interface.verifysig( \ - sig, msg, self.g1pubkey, '-sha512')) - - -def checkTempFiles(): - # check tmp files are not deleted - files = sh.ls().splitlines() - return 'ca_pubkey.pem' in files or 'tbs_certificate.bin' in files \ - or 'signature.bin' in files - - -class EpidCertificateTest(unittest.TestCase): - # EPID certificate file - cert0_f = '../testdata/cert0.cer' - # EPID key issuing CA certificate file, ECDSA key - cert1_f = '../testdata/cert1.cer' - # Root CA certificate file, ECDSA key - cert2_f = '../testdata/cert2.cer' - - # read files into buf - c0 = epid_interface.read_file(cert0_f) - c1 = epid_interface.read_file(cert1_f) - c2 = epid_interface.read_file(cert2_f) - - cert0 = decoder.decode(c0, asn1Spec=rfc5280.Certificate())[0] - cert1 = decoder.decode(c1, asn1Spec=rfc5280.Certificate())[0] - cert2 = decoder.decode(c2, asn1Spec=rfc5280.Certificate())[0] - - # test files read correctly - def testReadFile(self): - self.assertNotEqual(len(self.c0), 0) - self.assertNotEqual(len(self.c1), 0) - self.assertNotEqual(len(self.c2), 0) - - # test extract_public_key - def testExtractEpidPublicKeyEmpty(self): - with self.assertRaises(RuntimeError) as e: - epid_interface.extract_public_key('') - self.assertEqual(str(e.exception), 'public key format error') - - def testExtractEpidPublicKey0(self): - key = epid_interface.extract_public_key(self.c0) - self.assertEqual(len(key), 272) - - def testExtractEpidPublicKey1(self): - with self.assertRaises(RuntimeError) as e: - epid_interface.extract_public_key(self.c1) - self.assertEqual(str(e.exception), 'public key format error') - - # test extract_dgst - def testExtractDgstEmpty(self): - with self.assertRaises(RuntimeError) as e: - epid_interface.extract_dgst('') - self.assertEqual(str(e.exception), 'certificate format error') - - def testExtractDgst0(self): - dgst = epid_interface.extract_dgst(self.c0) - self.assertEqual(dgst, '-sha256') - - def testExtractDgstOidEmpty(self): - with self.assertRaises(RuntimeError) as e: - dgst = epid_interface.extract_dgst_oid('') - self.assertEqual(str(e.exception), 'dgst algorithm not supported') - - def testExtractDgstOid0(self): - with self.assertRaises(RuntimeError) as e: - dgst = epid_interface.extract_dgst_oid('1.2.840.10045.4.3.3') - self.assertEqual(str(e.exception), 'dgst algorithm not supported') - - def testExtractDgstOid0(self): - dgst = epid_interface.extract_dgst_oid('1.2.840.113741.1.9.4.3') - self.assertEqual(dgst, '-sha256') - - #test Certificate validity check - def testCertificateValidityTime1(self): - v = rfc5280.Validity() - time2 = datetime.datetime.utcnow() - time1 = time2 - datetime.timedelta(days=365) - v[0]['utcTime'] = v[0]['utcTime'].fromDateTime(time1) - v[1]['utcTime'] = v[1]['utcTime'].fromDateTime(time2) - res = epid_interface.verify_cert_validity(v) - self.assertEqual(res, 'FAIL certificate expired') - - def testCertificateValidityTime2(self): - v = rfc5280.Validity() - time1 = datetime.datetime.utcnow() + datetime.timedelta(days=1) - time2 = time1 + datetime.timedelta(days=365) - v[0]['utcTime'] = v[0]['utcTime'].fromDateTime(time1) - v[1]['utcTime'] = v[1]['utcTime'].fromDateTime(time2) - res = epid_interface.verify_cert_validity(v) - self.assertEqual(res, 'FAIL certificate not valid yet') - - def testCertificateValidityTime3(self): - v = rfc5280.Validity() - time1 = datetime.datetime.utcnow() - datetime.timedelta(days=1) - time2 = time1 + datetime.timedelta(days=2) - v[0]['utcTime'] = v[0]['utcTime'].fromDateTime(time1) - v[1]['utcTime'] = v[1]['utcTime'].fromDateTime(time2) - res = epid_interface.verify_cert_validity(v) - self.assertEqual(res, 'OKAY') - - def testCertificateValidityFormat1(self): - time1 = datetime.datetime.utcnow() - datetime.timedelta(days=1) - time2 = time1 + datetime.timedelta(days=2) - v = rfc5280.Validity() - v[0]['generalTime'] = v[0]['generalTime'].fromDateTime(time1) - v[1]['utcTime'] = v[1]['utcTime'].fromDateTime(time2) - res = epid_interface.verify_cert_validity(v) - self.assertEqual(res, 'FAIL certificate time format error') - - def testCertificateValidityFormat2(self): - time1 = datetime.datetime.utcnow() - datetime.timedelta(days=1) - time2 = time1 + datetime.timedelta(days=2) - v = rfc5280.Validity() - v[0]['utcTime'] = v[0]['utcTime'].fromDateTime(time1) - v[1]['generalTime'] = v[1]['generalTime'].fromDateTime(time2) - res = epid_interface.verify_cert_validity(v) - self.assertEqual(res, 'FAIL certificate time format error') - - def testCertificateValidityFormat3(self): - time1 = datetime.datetime.utcnow() - datetime.timedelta(days=1) - time2 = time1 + datetime.timedelta(days=2) - v = rfc5280.Validity() - v[0]['generalTime'] = v[0]['generalTime'].fromDateTime(time1) - v[1]['generalTime'] = v[1]['generalTime'].fromDateTime(time2) - res = epid_interface.verify_cert_validity(v) - self.assertEqual(res, 'FAIL certificate time format error') - - # test extension checks - def testExtensionCheckEmpty(self): - # empty extensions - ext = rfc5280.Extensions() - caext = rfc5280.Extensions() - res = epid_interface.verify_cert_exts(ext, caext) - self.assertEqual(res, 'FAIL signer is not capable of signing certificate') - - def testExtensionCheckInvalidId(self): - ext = rfc5280.Extension() - ext['extnID'] = ObjectIdentifier('1.2.840.10045.4.3.3') - # empty extensions - exts = rfc5280.Extensions() - caexts = rfc5280.Extensions() - exts.append(ext) - res = epid_interface.verify_cert_exts(exts, caexts) - self.assertEqual(res, 'FAIL certificate unrecognized extension') - - exts = rfc5280.Extensions() - caexts.append(ext) - res = epid_interface.verify_cert_exts(exts, caexts) - self.assertEqual(res, 'FAIL CA certificate unrecognized extension') - - def testExtensionCheckKeyIdentifiersFormat1(self): - ext = rfc5280.Extension() - caext = rfc5280.Extension() - caext['extnID'] = rfc5280.id_ce_subjectKeyIdentifier - caext['extnValue'] = '7712312' - exts = rfc5280.Extensions() - caexts = rfc5280.Extensions() - caexts.append(caext) - res = epid_interface.verify_cert_exts(exts, caexts) - self.assertEqual(res, 'FAIL subjectKeyIdentifier parsing error') - - def testExtensionCheckKeyIdentifiersFormat2(self): - exts = rfc5280.Extensions() - caexts = rfc5280.Extensions() - ext = rfc5280.Extension() - ext['extnID'] = rfc5280.id_ce_authorityKeyIdentifier - exts.setComponentByPosition(0, ext) - exts[0]['extnValue'] = '7712312' - res = epid_interface.verify_cert_exts(exts, caexts) - self.assertEqual(res, 'FAIL authorityKeyIdentifier parsing error') - - def testExtensionCheckKeyIdentifiersMatch1(self): - exts = rfc5280.Extensions() - caexts = rfc5280.Extensions() - # give cacert CA so that the check will pass - caexts.setComponentByPosition(0, - self.cert1['tbsCertificate']['extensions'][2]) - exts.setComponentByPosition(0, - self.cert0['tbsCertificate']['extensions'][0]) - res = epid_interface.verify_cert_exts(exts, caexts) - # identifiers matching check is not mandotory - # if authority or subject key ID is missing, check is expected to pass - self.assertEqual(res, 'OKAY') - - def testExtensionCheckKeyIdentifiersMatch2(self): - exts = rfc5280.Extensions() - caexts = rfc5280.Extensions() - # give cacert CA so that the check will pass - caexts.setComponentByPosition(0, - self.cert1['tbsCertificate']['extensions'][2]) - exts.setComponentByPosition(0, - self.cert0['tbsCertificate']['extensions'][0]) - caexts.setComponentByPosition(1, - self.cert1['tbsCertificate']['extensions'][5]) - res = epid_interface.verify_cert_exts(exts, caexts) - self.assertEqual(res, 'OKAY') - - def testExtensionCheckKeyIdentifiersMatch3(self): - exts = rfc5280.Extensions() - caexts = rfc5280.Extensions() - # give cacert CA so that the check will pass - caexts.setComponentByPosition(0, - self.cert1['tbsCertificate']['extensions'][2]) - caexts.setComponentByPosition(1, - self.cert1['tbsCertificate']['extensions'][5]) - exts.setComponentByPosition(0, - self.cert1['tbsCertificate']['extensions'][1]) - res = epid_interface.verify_cert_exts(exts, caexts) - self.assertTrue(res.startswith('FAIL key Identifiers mismatch')) - - def testBasicConstraints1(self): - exts = rfc5280.Extensions() - caexts = rfc5280.Extensions() - #cert CA true pathLen 0 - #cacert none - exts.setComponentByPosition(0, - self.cert1['tbsCertificate']['extensions'][2]) - res = epid_interface.verify_cert_exts(exts, caexts) - self.assertEqual(res, 'FAIL signer is not capable of signing certificate') - - def testBasicConstraints(self): - exts = rfc5280.Extensions() - caexts = rfc5280.Extensions() - #cert CA true pathLen 0 - #cacert CA true pathLen 0 - exts.setComponentByPosition(0, - self.cert1['tbsCertificate']['extensions'][2]) - caexts.setComponentByPosition(0, - self.cert1['tbsCertificate']['extensions'][2]) - res = epid_interface.verify_cert_exts(exts, caexts) - self.assertEqual(res, 'FAIL signer is not capable of authorizing CA') - - def testBasicConstraints(self): - exts = rfc5280.Extensions() - caexts = rfc5280.Extensions() - #cert CA true pathLen 2 - #cacert CA true pathLen 0 - caexts.setComponentByPosition(0, - self.cert1['tbsCertificate']['extensions'][2]) - exts.setComponentByPosition(0, - self.cert2['tbsCertificate']['extensions'][0]) - res = epid_interface.verify_cert_exts(exts, caexts) - self.assertEqual(res, 'FAIL signer is not capable of authorizing CA') - - def testBasicConstraints(self): - exts = rfc5280.Extensions() - caexts = rfc5280.Extensions() - #cert CA true pathLen 2 - #cacert CA true pathLen 2 - exts.setComponentByPosition(0, - self.cert2['tbsCertificate']['extensions'][0]) - caexts.setComponentByPosition(0, - self.cert2['tbsCertificate']['extensions'][0]) - res = epid_interface.verify_cert_exts(exts, caexts) - self.assertEqual(res, 'FAIL certificate pathlen is not permissible') - - # test Certificate checks - def testCertificate1(self): - res = epid_interface.verify_cert_file(self.cert0_f, self.cert1_f) - self.assertEqual('OKAY', res) - self.assertFalse(checkTempFiles()) - - def testCertificate2(self): - res = epid_interface.verify_cert_file(self.cert1_f, self.cert2_f) - self.assertEqual('OKAY', res) - self.assertFalse(checkTempFiles()) - - def testCertificate3(self): - res = epid_interface.verify_cert_file(self.cert1_f, self.cert0_f) - self.assertTrue(res.startswith('FAIL CA certificate parsing error')) - self.assertFalse(checkTempFiles()) - - def testCertificate4(self): - res = epid_interface.verify_cert_file(self.cert2_f, self.cert1_f) - self.assertTrue(res.startswith('FAIL signature check failed')) - self.assertFalse(checkTempFiles()) - - -if __name__ == '__main__': - unittest.main() diff --git a/epid/python_interface/libepid.so b/epid/python_interface/libepid.so Binary files differdeleted file mode 100755 index fbade4a..0000000 --- a/epid/python_interface/libepid.so +++ /dev/null diff --git a/epid/test/epid_unittest.cc b/epid/test/epid_unittest.cc deleted file mode 100644 index 68647fa..0000000 --- a/epid/test/epid_unittest.cc +++ /dev/null @@ -1,654 +0,0 @@ -/* - * Copyright 2018 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 "interface/signmsg.h" -#include "interface/verifysig.h" - -#include <cstdio> -#include <cstdlib> -#include <string> - -#include <base/files/file_util.h> -#include <gtest/gtest.h> - -class EpidTest : public ::testing::Test { - public: - // Fill string with random chars. - // Return false if fails. - bool random_msg(std::string* s); - // Simplified function to call EPID_Sign_atap - EpidStatus sign(const std::string& msg, - const std::string& privkey, - const std::string& precomp, - HashAlg alg, - std::string* sig, - size_t* sig_len); - // Simplified function to call EPID_Verify - EpidStatus verify(const std::string& msg, - const std::string& sig, - const std::string& pubkey, - const std::string& precomp, - HashAlg alg); - // generate precomp blob for signing - EpidStatus sign_precomp(const std::string& privkey, - std::string* precomp); - // generate precomp blob for verification - EpidStatus verify_precomp(const std::string& pubkey, - std::string* precomp); -}; - -constexpr char kEpidGroup1Pubkey[] = "testdata/group1pubkey.bin"; -constexpr char kEpidGroup1Privkey1[] = "testdata/group1privkey1.bin"; -constexpr char kEpidGroup1Privkey2[] = "testdata/group1privkey2.bin"; -constexpr char kEpidGroup1Privkey3[] = "testdata/group1privkey3.bin"; -constexpr char kEpidGroup2Pubkey[] = "testdata/group2pubkey.bin"; -constexpr char kEpidGroup2Privkey1[] = "testdata/group2privkey1.bin"; -constexpr char kEpidGroup2Privkey2[] = "testdata/group2privkey2.bin"; -constexpr char kEpidGroup2Privkey3[] = "testdata/group2privkey3.bin"; - -constexpr size_t kEpidSigLen = 360; -constexpr size_t kEpidSignPrecompLen = 1536; -constexpr size_t kEpidVerifyPrecompLen = 1552; - -bool EpidTest::random_msg(std::string* s) { - if (s->empty()) return true; - FILE* f = fopen("/dev/urandom", "rb"); - if (f) { - size_t ret = fread((void*)s->data(), 1, s->size(), f); - fclose(f); - return ret == s->size(); - } else { - return false; - } -} - -EpidStatus EpidTest::sign(const std::string& msg, const std::string& privkey, - const std::string& precomp, HashAlg alg, - std::string* sig, size_t* sig_len) { - return EpidApiSignAtap(msg.data(), msg.size(), nullptr, 0, privkey.data(), - privkey.size(), nullptr, 0, precomp.data(), - precomp.size(), alg, &(*sig)[0], sig_len); -} - -EpidStatus EpidTest::verify(const std::string& msg, const std::string& sig, - const std::string& pubkey, - const std::string& precomp, HashAlg alg) { - return EpidApiVerify(sig.data(), sig.size(), msg.data(), msg.size(), nullptr, - 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, - pubkey.data(), pubkey.size(), precomp.data(), - precomp.size(), alg); -} - -EpidStatus EpidTest::sign_precomp(const std::string& privkey, - std::string* precomp) { - return EpidApiSignPrecomp(privkey.data(), privkey.size(), - &(*precomp)[0], precomp->size()); -} - -EpidStatus EpidTest::verify_precomp(const std::string& privkey, - std::string* precomp) { - return EpidApiVerifyPrecomp(privkey.data(), privkey.size(), - &(*precomp)[0], precomp->size()); -} - -TEST_F(EpidTest, SignMsgGroup1Privkey1Wrongkey) { - // modify private key - std::string privkey, pubkey; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), &privkey)); - - std::string precomps, precompv; - std::string msg("test message"); - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kSha256; - EpidStatus status = kEpidErr; - - // modify key - privkey[privkey.size() - 1] = 0; - status = sign(msg, privkey, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidBadArgErr); -} - -TEST_F(EpidTest, SignVerifyMsgGroup1Privkey1MultipleSign) { - // test repeated signatures for the same message are not identical - // and all signatures pass verification - std::string privkey, pubkey; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), &privkey)); - - std::string msg("test message"); - std::string sig1(kEpidSigLen, 0); - std::string sig2(kEpidSigLen, 0); - std::string sig3(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kSha256; - EpidStatus status = kEpidErr; - - std::string precomps(kEpidSignPrecompLen, 0), precompv; - status = sign_precomp(privkey, &precomps); - EXPECT_EQ(status, kEpidNoErr); - - // sign same message three times - status = sign(msg, privkey, precomps, alg, &sig1, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - ASSERT_EQ(sig_len, kEpidSigLen); - status = sign(msg, privkey, precomps, alg, &sig2, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - ASSERT_EQ(sig_len, kEpidSigLen); - status = sign(msg, privkey, precomps, alg, &sig3, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - ASSERT_EQ(sig_len, kEpidSigLen); - EXPECT_NE(sig1, sig2); - EXPECT_NE(sig1, sig3); - EXPECT_NE(sig2, sig3); - - // verify three signatures against the same message - status = verify(msg, sig1, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidNoErr); - status = verify(msg, sig2, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidNoErr); - status = verify(msg, sig3, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidNoErr); -} - -TEST_F(EpidTest, SignVerifyMsgGroup1Privkey1MultipleSignPrecomp) { - // test repeated signatures for the same message are not identical - // and all signatures pass verification - // use precomp - std::string privkey, pubkey; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), &privkey)); - - std::string msg("test message"); - std::string sig1(kEpidSigLen, 0); - std::string sig2(kEpidSigLen, 0); - std::string sig3(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kSha256; - EpidStatus status = kEpidErr; - - // precomp - std::string precomps(kEpidSignPrecompLen, 0); - std::string precompv(kEpidVerifyPrecompLen, 0); - status = sign_precomp(privkey, &precomps); - EXPECT_EQ(status, kEpidNoErr); - status = verify_precomp(pubkey, &precompv); - EXPECT_EQ(status, kEpidNoErr); - - // sign same message three times - status = sign(msg, privkey, precomps, alg, &sig1, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - ASSERT_EQ(sig_len, kEpidSigLen); - status = sign(msg, privkey, precomps, alg, &sig2, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - ASSERT_EQ(sig_len, kEpidSigLen); - status = sign(msg, privkey, precomps, alg, &sig3, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - ASSERT_EQ(sig_len, kEpidSigLen); - EXPECT_NE(sig1, sig2); - EXPECT_NE(sig1, sig3); - EXPECT_NE(sig2, sig3); - - // verify three signatures against the same message - status = verify(msg, sig1, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidNoErr); - status = verify(msg, sig2, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidNoErr); - status = verify(msg, sig3, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidNoErr); -} - -TEST_F(EpidTest, SignVerifyMsgGroup1Privkey1HashAlgos) { - // sign with group1 private key1 and verify with different hash algos - std::string privkey, pubkey; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), &privkey)); - - EpidStatus status = kEpidErr; - std::string precomps, precompv; - - // test differnt hash algos sign/verify - // supported Hash algos: sha256 sha384 sha512 sha512_256 - for (int i = 0; i <= 3; ++i) { - std::string msg("test message"); - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = (HashAlg)i; - - status = sign(msg, privkey, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - EXPECT_EQ(sig_len, kEpidSigLen); - - // verify with differernt hash algo - // matched algos should succeed - // mismatched algos should fail - for (int j = 0; j <= 3; ++j) { - HashAlg alg1 = (HashAlg)j; - status = verify(msg, sig, pubkey, precompv, alg1); - if (alg == alg1) { - EXPECT_EQ(status, kEpidNoErr); - } else { - EXPECT_EQ(status, kEpidSigInvalid); - } - } - } - - // test unsupported hash algo - std::string msg("test message"); - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kInvalidHashAlg; - - status = sign(msg, privkey, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidBadArgErr); - status = verify(msg, sig, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidBadArgErr); - - alg = kSha3_512; - status = sign(msg, privkey, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidBadArgErr); - status = verify(msg, sig, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidBadArgErr); -} - -TEST_F(EpidTest, SignVerifyMsgGroup1Privkey1HashAlgosPrecomp) { - // sign with group1 private key1 and verify with different hash algos - // use precompute to speed up - std::string privkey, pubkey; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), &privkey)); - - EpidStatus status = kEpidErr; - - std::string precomps(kEpidSignPrecompLen, 0); - status = sign_precomp(privkey, &precomps); - EXPECT_EQ(status, kEpidNoErr); - - std::string precompv(kEpidVerifyPrecompLen, 0); - status = verify_precomp(pubkey, &precompv); - EXPECT_EQ(status, kEpidNoErr); - - // test differnt hash algos sign/verify - // supported Hash algos: sha256 sha384 sha512 sha512_256 - for (int i = 0; i <= 3; ++i) { - std::string msg("test message"); - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = (HashAlg)i; - - status = sign(msg, privkey, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - EXPECT_EQ(sig_len, kEpidSigLen); - - // verify with differernt hash algo - // matched algos should succeed - // mismatched algos should fail - for (int j = 0; j <= 3; ++j) { - HashAlg alg1 = (HashAlg)j; - status = verify(msg, sig, pubkey, precompv, alg1); - if (alg == alg1) { - EXPECT_EQ(status, kEpidNoErr); - } else { - EXPECT_EQ(status, kEpidSigInvalid); - } - } - } - - // test unsupported hash algo - std::string msg("test message"); - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kInvalidHashAlg; - - status = sign(msg, privkey, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidBadArgErr); - status = verify(msg, sig, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidBadArgErr); - - alg = kSha3_512; - status = sign(msg, privkey, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidBadArgErr); - status = verify(msg, sig, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidBadArgErr); -} - -TEST_F(EpidTest, SignVerifyMsgAllGroupsAllPrivkeys) { - // sign with private keys and verify with group public keys - // two EPID groups, each with 3 private keys, are tested - std::string privkey[2][3], pubkey[2]; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey[0])); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup2Pubkey), &pubkey[1])); - ASSERT_TRUE(base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), - &privkey[0][0])); - ASSERT_TRUE(base::ReadFileToString(base::FilePath(kEpidGroup1Privkey2), - &privkey[0][1])); - ASSERT_TRUE(base::ReadFileToString(base::FilePath(kEpidGroup1Privkey3), - &privkey[0][2])); - ASSERT_TRUE(base::ReadFileToString(base::FilePath(kEpidGroup2Privkey1), - &privkey[1][0])); - ASSERT_TRUE(base::ReadFileToString(base::FilePath(kEpidGroup2Privkey2), - &privkey[1][1])); - ASSERT_TRUE(base::ReadFileToString(base::FilePath(kEpidGroup2Privkey3), - &privkey[1][2])); - - // test differnt groups - for (int i = 0; i < 6; ++i) { - int group = i / 3; - int member = i % 3; - - std::string msg("test message"); - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kSha256; - EpidStatus status = kEpidErr; - std::string precomps, precompv; - - status = sign(msg, privkey[group][member], precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - EXPECT_EQ(sig_len, kEpidSigLen); - - status = verify(msg, sig, pubkey[group], precompv, alg); - EXPECT_EQ(status, kEpidNoErr); - } -} - -TEST_F(EpidTest, SignVerifyMsgGroup1Privkey1MismatchMsg) { - // read public/private keys - std::string privkey, pubkey; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey3), &privkey)); - - const size_t kMsgLen = 10; - std::string msg1(kMsgLen, 0); - std::string msg2(kMsgLen, 0); - while (msg1 == msg2) { - ASSERT_TRUE(random_msg(&msg1)); - ASSERT_TRUE(random_msg(&msg2)); - } - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kSha256; - EpidStatus status = kEpidErr; - std::string precomps, precompv; - - status = sign(msg1, privkey, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - EXPECT_EQ(sig_len, kEpidSigLen); - - status = verify(msg2, sig, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidSigInvalid); -} - -TEST_F(EpidTest, SignVerifyMsgMismatchGroupKey) { - // sign with privkey and verify with pubkey of other group - std::string privkey[2][3], pubkey[2]; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey[0])); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup2Pubkey), &pubkey[1])); - ASSERT_TRUE(base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), - &privkey[0][0])); - ASSERT_TRUE(base::ReadFileToString(base::FilePath(kEpidGroup1Privkey2), - &privkey[0][1])); - ASSERT_TRUE(base::ReadFileToString(base::FilePath(kEpidGroup1Privkey3), - &privkey[0][2])); - ASSERT_TRUE(base::ReadFileToString(base::FilePath(kEpidGroup2Privkey1), - &privkey[1][0])); - ASSERT_TRUE(base::ReadFileToString(base::FilePath(kEpidGroup2Privkey2), - &privkey[1][1])); - ASSERT_TRUE(base::ReadFileToString(base::FilePath(kEpidGroup2Privkey3), - &privkey[1][2])); - - std::string msg("test message"); - - for (int i = 0; i < 6; ++i) { - int group = i / 3; - int other_group = (group == 0 ? 1 : 0); - int member = i % 3; - - std::string msg("test message"); - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kSha256; - EpidStatus status = kEpidErr; - std::string precomps, precompv; - - status = sign(msg, privkey[group][member], precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - EXPECT_EQ(sig_len, kEpidSigLen); - - status = verify(msg, sig, pubkey[other_group], precompv, alg); - EXPECT_EQ(status, kEpidSigInvalid); - } -} - -TEST_F(EpidTest, SignWithPrecomp) { - // generate precomp instances to speed up signing - std::string privkey, pubkey; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), &privkey)); - - std::string precomps(kEpidSignPrecompLen, 0), precompv; - std::string msg("test message"); - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kSha256; - EpidStatus status = kEpidErr; - - // do precomp - status = sign_precomp(privkey, &precomps); - EXPECT_EQ(status, kEpidNoErr); - - // sign with precomp - status = sign(msg, privkey, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - EXPECT_EQ(sig_len, kEpidSigLen); - - status = verify(msg, sig, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidNoErr); -} - -TEST_F(EpidTest, SignWithPrecompMismatchKey) { - // generate precomp instances and sign with mismatched key - std::string privkey1, privkey2, pubkey; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), &privkey1)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey2), &privkey2)); - - std::string precomps(kEpidSignPrecompLen, 0), precompv; - std::string msg("test message"); - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kSha256; - EpidStatus status = kEpidErr; - - // do precomp - status = sign_precomp(privkey1, &precomps); - EXPECT_EQ(status, kEpidNoErr); - - // sign with mismtached precomp - status = sign(msg, privkey2, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - EXPECT_EQ(sig_len, kEpidSigLen); - - status = verify(msg, sig, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidSigInvalid); -} - -TEST_F(EpidTest, SignWithPrecompMismatchGroup) { - // generate precomp instances and sign with mismatched key - std::string privkey1, privkey2, pubkey; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), &privkey1)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup2Privkey1), &privkey2)); - - std::string precomps(kEpidSignPrecompLen, 0), precompv; - std::string msg("test message"); - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kSha256; - EpidStatus status = kEpidErr; - - // do precomp - status = sign_precomp(privkey1, &precomps); - EXPECT_EQ(status, kEpidNoErr); - - // sign with precomp - status = sign(msg, privkey2, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - EXPECT_EQ(sig_len, kEpidSigLen); - - status = verify(msg, sig, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidSigInvalid); -} - -TEST_F(EpidTest, VerifyWithPrecomp) { - // generate precomp instances and sign with mismatched key - std::string privkey1, privkey2, pubkey; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), &privkey1)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey2), &privkey2)); - - std::string precomps, precompv(kEpidVerifyPrecompLen, 0); - std::string msg("test message"); - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kSha256; - EpidStatus status = kEpidErr; - - // do precomp - status = verify_precomp(pubkey, &precompv); - EXPECT_EQ(status, kEpidNoErr); - - // sign - status = sign(msg, privkey1, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - EXPECT_EQ(sig_len, kEpidSigLen); - - // verify with precomp - status = verify(msg, sig, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidNoErr); - - // sign again - status = sign(msg, privkey2, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - EXPECT_EQ(sig_len, kEpidSigLen); - - // verify with precomp - status = verify(msg, sig, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidNoErr); - - alg = kSha512; - // sign again - status = sign(msg, privkey2, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - EXPECT_EQ(sig_len, kEpidSigLen); - - // verify with precomp - status = verify(msg, sig, pubkey, precompv, alg); - EXPECT_EQ(status, kEpidNoErr); -} - -TEST_F(EpidTest, VerifyWithPrecompMismatchGroup) { - // generate precomp instances and sign with mismatched key - std::string privkey, pubkey1, pubkey2; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey1)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), &privkey)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup2Pubkey), &pubkey2)); - - std::string precomps, precompv(kEpidVerifyPrecompLen, 0); - std::string msg("test message"); - std::string sig(kEpidSigLen, 0); - size_t sig_len = 0; - HashAlg alg = kSha256; - EpidStatus status = kEpidErr; - - // do precomp - status = verify_precomp(pubkey2, &precompv); - EXPECT_EQ(status, kEpidNoErr); - - // sign - status = sign(msg, privkey, precomps, alg, &sig, &sig_len); - EXPECT_EQ(status, kEpidNoErr); - EXPECT_EQ(sig_len, kEpidSigLen); - - // verify with precomp - status = verify(msg, sig, pubkey1, precompv, alg); - EXPECT_EQ(status, kEpidBadArgErr); -} - -TEST_F(EpidTest, PrecompBadInput) { - // precomp input invalid - std::string privkey, pubkey; - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Pubkey), &pubkey)); - ASSERT_TRUE( - base::ReadFileToString(base::FilePath(kEpidGroup1Privkey1), &privkey)); - - std::string precomps, precompv; - EpidStatus status = kEpidErr; - - // do precomp - status = sign_precomp(privkey, &precomps); - EXPECT_EQ(status, kEpidBadArgErr); - - precomps.resize(kEpidSignPrecompLen - 1); - status = sign_precomp(privkey, &precomps); - EXPECT_EQ(status, kEpidBadArgErr); - precomps.resize(kEpidSignPrecompLen + 1); - status = sign_precomp(privkey, &precomps); - EXPECT_EQ(status, kEpidBadArgErr); - - // do precomp - status = verify_precomp(pubkey, &precompv); - EXPECT_EQ(status, kEpidBadArgErr); - - precompv.resize(kEpidVerifyPrecompLen - 1); - status = verify_precomp(pubkey, &precompv); - EXPECT_EQ(status, kEpidBadArgErr); - precompv.resize(kEpidVerifyPrecompLen + 1); - status = verify_precomp(pubkey, &precompv); - EXPECT_EQ(status, kEpidBadArgErr); -} diff --git a/epid/testdata/cert0.cer b/epid/testdata/cert0.cer Binary files differdeleted file mode 100644 index 87f3941..0000000 --- a/epid/testdata/cert0.cer +++ /dev/null diff --git a/epid/testdata/cert1.cer b/epid/testdata/cert1.cer Binary files differdeleted file mode 100644 index fd45e3b..0000000 --- a/epid/testdata/cert1.cer +++ /dev/null diff --git a/epid/testdata/cert2.cer b/epid/testdata/cert2.cer Binary files differdeleted file mode 100644 index 8ee8778..0000000 --- a/epid/testdata/cert2.cer +++ /dev/null diff --git a/epid/testdata/group1privkey1.bin b/epid/testdata/group1privkey1.bin Binary files differdeleted file mode 100644 index fe4ce23..0000000 --- a/epid/testdata/group1privkey1.bin +++ /dev/null diff --git a/epid/testdata/group1privkey2.bin b/epid/testdata/group1privkey2.bin Binary files differdeleted file mode 100644 index a231edc..0000000 --- a/epid/testdata/group1privkey2.bin +++ /dev/null diff --git a/epid/testdata/group1privkey3.bin b/epid/testdata/group1privkey3.bin Binary files differdeleted file mode 100644 index 9ad6a22..0000000 --- a/epid/testdata/group1privkey3.bin +++ /dev/null diff --git a/epid/testdata/group1pubkey.bin b/epid/testdata/group1pubkey.bin Binary files differdeleted file mode 100644 index a1cc1ce..0000000 --- a/epid/testdata/group1pubkey.bin +++ /dev/null diff --git a/epid/testdata/group2privkey1.bin b/epid/testdata/group2privkey1.bin Binary files differdeleted file mode 100644 index 7ca5104..0000000 --- a/epid/testdata/group2privkey1.bin +++ /dev/null diff --git a/epid/testdata/group2privkey2.bin b/epid/testdata/group2privkey2.bin Binary files differdeleted file mode 100644 index cbe9cd6..0000000 --- a/epid/testdata/group2privkey2.bin +++ /dev/null diff --git a/epid/testdata/group2privkey3.bin b/epid/testdata/group2privkey3.bin Binary files differdeleted file mode 100644 index e0a7b82..0000000 --- a/epid/testdata/group2privkey3.bin +++ /dev/null diff --git a/epid/testdata/group2pubkey.bin b/epid/testdata/group2pubkey.bin Binary files differdeleted file mode 100644 index 719ee1e..0000000 --- a/epid/testdata/group2pubkey.bin +++ /dev/null |