• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*############################################################################
2   # Copyright 2016-2017 Intel Corporation
3   #
4   # Licensed under the Apache License, Version 2.0 (the "License");
5   # you may not use this file except in compliance with the License.
6   # You may obtain a copy of the License at
7   #
8   #     http://www.apache.org/licenses/LICENSE-2.0
9   #
10   # Unless required by applicable law or agreed to in writing, software
11   # distributed under the License is distributed on an "AS IS" BASIS,
12   # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   # See the License for the specific language governing permissions and
14   # limitations under the License.
15   ############################################################################*/
16 /// Message signing implementation.
17 /*!
18  * \file
19  *
20  * This file has a corresponding walk-through in the SDK documentation.
21  *
22  * Review the walk-through for correctness after making changes to this
23  * file.
24  */
25 #include "src/signmsg.h"
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include "epid/common/file_parser.h"
30 #include "epid/member/api.h"
31 #include "src/prng.h"
32 #include "util/convutil.h"
33 
SignMsg(void const * msg,size_t msg_len,void const * basename,size_t basename_len,unsigned char const * signed_sig_rl,size_t signed_sig_rl_size,unsigned char const * signed_pubkey,size_t signed_pubkey_size,unsigned char const * priv_key_ptr,size_t privkey_size,HashAlg hash_alg,MemberPrecomp * member_precomp,EpidSignature ** sig,size_t * sig_len,EpidCaCertificate const * cacert)34 EpidStatus SignMsg(void const* msg, size_t msg_len, void const* basename,
35                    size_t basename_len, unsigned char const* signed_sig_rl,
36                    size_t signed_sig_rl_size,
37                    unsigned char const* signed_pubkey,
38                    size_t signed_pubkey_size, unsigned char const* priv_key_ptr,
39                    size_t privkey_size, HashAlg hash_alg,
40                    MemberPrecomp* member_precomp, EpidSignature** sig,
41                    size_t* sig_len, EpidCaCertificate const* cacert) {
42   EpidStatus sts = kEpidErr;
43   void* prng = NULL;
44   MemberCtx* member = NULL;
45   SigRl* sig_rl = NULL;
46 
47   do {
48     GroupPubKey pub_key = {0};
49     PrivKey priv_key = {0};
50     MembershipCredential member_credential = {0};
51     size_t sig_rl_size = 0;
52     MemberParams params = {0};
53     size_t member_size = 0;
54 
55     if (!sig) {
56       sts = kEpidBadArgErr;
57       break;
58     }
59 
60     // authenticate and extract group public key
61     sts = EpidParseGroupPubKeyFile(signed_pubkey, signed_pubkey_size, cacert,
62                                    &pub_key);
63     if (kEpidNoErr != sts) {
64       break;
65     }
66     // handle compressed private key or membership credential
67     if (privkey_size == sizeof(PrivKey)) {
68       priv_key = *(PrivKey*)priv_key_ptr;
69     } else if (privkey_size == sizeof(CompressedPrivKey)) {
70       sts = EpidDecompressPrivKey(&pub_key, (CompressedPrivKey*)priv_key_ptr,
71                                   &priv_key);
72       if (kEpidNoErr != sts) {
73         break;
74       }
75     } else if (privkey_size == sizeof(MembershipCredential)) {
76       member_credential = *(MembershipCredential*)priv_key_ptr;
77     } else {
78       sts = kEpidErr;
79       break;
80     }  // if (privkey_size == sizeof(PrivKey))
81 
82     // acquire PRNG
83     sts = PrngCreate(&prng);
84     if (kEpidNoErr != sts) {
85       break;
86     }
87 
88     SetMemberParams(&PrngGen, prng, NULL, &params);
89     // create member
90     sts = EpidMemberGetSize(&params, &member_size);
91     if (kEpidNoErr != sts) {
92       break;
93     }
94     member = (MemberCtx*)calloc(1, member_size);
95     if (!member) {
96       sts = kEpidNoMemErr;
97       break;
98     }
99     sts = EpidMemberInit(&params, member);
100     if (kEpidNoErr != sts) {
101       break;
102     }
103 
104     sts = EpidMemberSetHashAlg(member, hash_alg);
105     if (kEpidNoErr != sts) {
106       break;
107     }
108 
109     if (privkey_size == sizeof(PrivKey) ||
110         privkey_size == sizeof(CompressedPrivKey)) {
111       sts = EpidProvisionKey(member, &pub_key, &priv_key, member_precomp);
112       if (kEpidNoErr != sts) {
113         break;
114       }
115     } else if (privkey_size == sizeof(MembershipCredential)) {
116       sts = EpidProvisionCredential(member, &pub_key, &member_credential,
117                                     member_precomp);
118       if (kEpidNoErr != sts) {
119         break;
120       }
121     }  // if (privkey_size == sizeof(PrivKey))
122     // start member
123     sts = EpidMemberStartup(member);
124     if (kEpidNoErr != sts) {
125       break;
126     }
127 
128     // register any provided basename as allowed
129     if (0 != basename_len) {
130       sts = EpidRegisterBasename(member, basename, basename_len);
131       if (kEpidNoErr != sts) {
132         break;
133       }
134     }
135 
136     if (signed_sig_rl) {
137       // authenticate and determine space needed for SigRl
138       sts = EpidParseSigRlFile(signed_sig_rl, signed_sig_rl_size, cacert, NULL,
139                                &sig_rl_size);
140       if (kEpidSigInvalid == sts) {
141         // authentication failure
142         break;
143       }
144       if (kEpidNoErr != sts) {
145         break;
146       }
147       sig_rl = calloc(1, sig_rl_size);
148       if (!sig_rl) {
149         sts = kEpidMemAllocErr;
150         break;
151       }
152 
153       // fill the SigRl
154       sts = EpidParseSigRlFile(signed_sig_rl, signed_sig_rl_size, cacert,
155                                sig_rl, &sig_rl_size);
156       if (kEpidSigInvalid == sts) {
157         // authentication failure
158         break;
159       }
160       if (kEpidNoErr != sts) {
161         break;
162       }
163 
164       sts = EpidMemberSetSigRl(member, sig_rl, sig_rl_size);
165       if (kEpidNoErr != sts) {
166         break;
167       }
168     }  // if (signed_sig_rl)
169 
170     // Signature
171     // Note: Signature size must be computed after sig_rl is loaded.
172     *sig_len = EpidGetSigSize(sig_rl);
173 
174     *sig = calloc(1, *sig_len);
175     if (!*sig) {
176       sts = kEpidMemAllocErr;
177       break;
178     }
179 
180     // sign message
181     sts =
182         EpidSign(member, msg, msg_len, basename, basename_len, *sig, *sig_len);
183     if (kEpidNoErr != sts) {
184       break;
185     }
186     sts = kEpidNoErr;
187   } while (0);
188 
189   PrngDelete(&prng);
190   EpidMemberDeinit(member);
191   if (member) free(member);
192 
193   if (sig_rl) free(sig_rl);
194 
195   return sts;
196 }
197