• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * This file is part of the openHiTLS project.
3  *
4  * openHiTLS is licensed under the Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *
8  *     http://license.coscl.org.cn/MulanPSL2
9  *
10  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13  * See the Mulan PSL v2 for more details.
14  */
15 #include <stdint.h>
16 #include "securec.h"
17 #include "bsl_errno.h"
18 #include "bsl_err_internal.h"
19 #include "bsl_sal.h"
20 #include "bsl_bytes.h"
21 #include "auth_errno.h"
22 #include "auth_params.h"
23 #include "auth_privpass_token.h"
24 #include "privpass_token.h"
25 
26 #define PRIVPASS_TOKEN_MAX_ENCODE_PUBKEY_LEN 1024
27 
SetAndValidateTokenType(const BSL_Param * param,PrivPass_TokenChallenge * tokenChallenge)28 static int32_t SetAndValidateTokenType(const BSL_Param *param, PrivPass_TokenChallenge *tokenChallenge)
29 {
30     const BSL_Param *temp = BSL_PARAM_FindConstParam(param, AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_TYPE);
31     if (temp == NULL) {
32         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_TYPE);
33         return HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_TYPE;
34     }
35 
36     uint32_t tokenTypeLen = (uint32_t)sizeof(tokenChallenge->tokenType);
37     uint16_t tokenType = 0;
38     int32_t ret = BSL_PARAM_GetValue(temp, AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_TYPE, BSL_PARAM_TYPE_UINT16,
39         &tokenType, &tokenTypeLen);
40     if (ret != BSL_SUCCESS) {
41         BSL_ERR_PUSH_ERROR(ret);
42         return ret;
43     }
44     if (tokenType != PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
45         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
46         return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
47     }
48     tokenChallenge->tokenType = tokenType;
49     return HITLS_AUTH_SUCCESS;
50 }
51 
SetIssuerName(const BSL_Param * param,PrivPass_TokenChallenge * tokenChallenge)52 static int32_t SetIssuerName(const BSL_Param *param, PrivPass_TokenChallenge *tokenChallenge)
53 {
54     const BSL_Param *temp = BSL_PARAM_FindConstParam(param, AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_ISSUERNAME);
55     if (temp == NULL) {
56         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_ISSUERNAME);
57         return HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_ISSUERNAME;
58     }
59 
60     if (temp->valueLen == 0 || temp->valueLen > PRIVPASS_MAX_ISSUER_NAME_LEN) {
61         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_ISSUER_NAME);
62         return HITLS_AUTH_PRIVPASS_INVALID_ISSUER_NAME;
63     }
64 
65     tokenChallenge->issuerName.data = BSL_SAL_Dump(temp->value, temp->valueLen);
66     if (tokenChallenge->issuerName.data == NULL) {
67         BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
68         return BSL_DUMP_FAIL;
69     }
70     tokenChallenge->issuerName.dataLen = temp->valueLen;
71     return HITLS_AUTH_SUCCESS;
72 }
73 
SetOptionalFields(const BSL_Param * param,PrivPass_TokenChallenge * tokenChallenge)74 static int32_t SetOptionalFields(const BSL_Param *param, PrivPass_TokenChallenge *tokenChallenge)
75 {
76     // Set redemption
77     const BSL_Param *temp = BSL_PARAM_FindConstParam(param, AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_REDEMPTION);
78     if (temp == NULL) {
79         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_REDEMPTION);
80         return HITLS_AUTH_PRIVPASS_NO_TOKEN_CHALLENGE_REDEMPTION;
81     }
82     if (temp->valueLen != 0) {
83         if (temp->valueLen != PRIVPASS_REDEMPTION_LEN) {
84             BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_REDEMPTION);
85             return HITLS_AUTH_PRIVPASS_INVALID_REDEMPTION;
86         }
87         tokenChallenge->redemption.data = BSL_SAL_Dump(temp->value, temp->valueLen);
88         if (tokenChallenge->redemption.data == NULL) {
89             BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
90             return BSL_DUMP_FAIL;
91         }
92         tokenChallenge->redemption.dataLen = temp->valueLen;
93     }
94 
95     // Set originInfo (optional)
96     temp = BSL_PARAM_FindConstParam(param, AUTH_PARAM_PRIVPASS_TOKENCHALLENGE_ORIGININFO);
97     if (temp != NULL && temp->valueLen > 0) {
98         if (temp->valueLen > PRIVPASS_MAX_ORIGIN_INFO_LEN) {
99             BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_ORIGIN_INFO);
100             return HITLS_AUTH_PRIVPASS_INVALID_ORIGIN_INFO;
101         }
102         tokenChallenge->originInfo.data = BSL_SAL_Dump(temp->value, temp->valueLen);
103         if (tokenChallenge->originInfo.data == NULL) {
104             BSL_ERR_PUSH_ERROR(BSL_DUMP_FAIL);
105             return BSL_DUMP_FAIL;
106         }
107         tokenChallenge->originInfo.dataLen = temp->valueLen;
108     }
109     return HITLS_AUTH_SUCCESS;
110 }
111 
HITLS_AUTH_PrivPassGenTokenChallenge(HITLS_AUTH_PrivPassCtx * ctx,const BSL_Param * param,HITLS_AUTH_PrivPassToken ** challenge)112 int32_t HITLS_AUTH_PrivPassGenTokenChallenge(HITLS_AUTH_PrivPassCtx *ctx, const BSL_Param *param,
113     HITLS_AUTH_PrivPassToken **challenge)
114 {
115     (void)ctx;
116     if (param == NULL || challenge == NULL || *challenge != NULL) {
117         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
118         return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
119     }
120 
121     HITLS_AUTH_PrivPassToken *output = HITLS_AUTH_PrivPassNewToken(HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE);
122     if (output == NULL) {
123         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
124         return BSL_MALLOC_FAIL;
125     }
126     uint64_t challengeLen;
127     PrivPass_TokenChallenge *tokenChallenge = output->st.tokenChallenge;
128     int32_t ret = SetAndValidateTokenType(param, tokenChallenge);
129     if (ret != HITLS_AUTH_SUCCESS) {
130         HITLS_AUTH_PrivPassFreeToken(output);
131         return ret;
132     }
133 
134     ret = SetIssuerName(param, tokenChallenge);
135     if (ret != HITLS_AUTH_SUCCESS) {
136         HITLS_AUTH_PrivPassFreeToken(output);
137         return ret;
138     }
139 
140     ret = SetOptionalFields(param, tokenChallenge);
141     if (ret != HITLS_AUTH_SUCCESS) {
142         HITLS_AUTH_PrivPassFreeToken(output);
143         return ret;
144     }
145     challengeLen = sizeof(tokenChallenge->tokenType) + tokenChallenge->issuerName.dataLen +
146         tokenChallenge->redemption.dataLen + tokenChallenge->originInfo.dataLen;
147     if (challengeLen > UINT32_MAX) {
148         HITLS_AUTH_PrivPassFreeToken(output);
149         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE_PARAM);
150         return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE_PARAM;
151     }
152     *challenge = output;
153     return HITLS_AUTH_SUCCESS;
154 }
155 
ParamCheckOfGenTokenReq(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,HITLS_AUTH_PrivPassToken ** tokenRequest)156 static int32_t ParamCheckOfGenTokenReq(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
157     HITLS_AUTH_PrivPassToken **tokenRequest)
158 {
159     if (ctx == NULL || ctx->method.blind == NULL || ctx->method.digest == NULL || ctx->method.random == NULL ||
160         tokenChallenge == NULL || tokenChallenge->type != HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE ||
161         tokenRequest == NULL || *tokenRequest != NULL) {
162         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
163         return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
164     }
165     if (tokenChallenge->st.tokenChallenge->tokenType != PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
166         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
167         return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
168     }
169     if (ctx->pubKeyCtx == NULL) {
170         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO);
171         return HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO;
172     }
173     return HITLS_AUTH_SUCCESS;
174 }
175 
ObtainAuthenticatorLen(uint16_t tokenType)176 static uint32_t ObtainAuthenticatorLen(uint16_t tokenType)
177 {
178     if (tokenType == PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
179         return (uint32_t)PRIVPASS_TOKEN_NK;
180     }
181     return 0;
182 }
183 
GenerateChallengeDigest(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,uint8_t * challengeDigest)184 static int32_t GenerateChallengeDigest(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
185     uint8_t *challengeDigest)
186 {
187     uint8_t *challenge = NULL;
188     uint32_t challengeLen = 0;
189     uint32_t challengeDigestLen = PRIVPASS_TOKEN_SHA256_SIZE;
190     int32_t ret = HITLS_AUTH_PrivPassSerialization(ctx, tokenChallenge, NULL, &challengeLen);
191     if (ret != HITLS_AUTH_SUCCESS) {
192         BSL_ERR_PUSH_ERROR(ret);
193         return ret;
194     }
195     challenge = BSL_SAL_Malloc(challengeLen);
196     if (challenge == NULL) {
197         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
198         return BSL_MALLOC_FAIL;
199     }
200     ret = HITLS_AUTH_PrivPassSerialization(ctx, tokenChallenge, challenge, &challengeLen);
201     if (ret != HITLS_AUTH_SUCCESS) {
202         BSL_SAL_Free(challenge);
203         BSL_ERR_PUSH_ERROR(ret);
204         return ret;
205     }
206     ret = ctx->method.digest(NULL, NULL, HITLS_AUTH_PRIVPASS_CRYPTO_SHA256, challenge, challengeLen, challengeDigest,
207         &challengeDigestLen);
208     BSL_SAL_Free(challenge);
209     if (ret != HITLS_AUTH_SUCCESS) {
210         BSL_ERR_PUSH_ERROR(ret);
211     }
212     return ret;
213 }
214 
HITLS_AUTH_PrivPassGenTokenReq(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,HITLS_AUTH_PrivPassToken ** tokenRequest)215 int32_t HITLS_AUTH_PrivPassGenTokenReq(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
216     HITLS_AUTH_PrivPassToken **tokenRequest)
217 {
218     int32_t ret = ParamCheckOfGenTokenReq(ctx, tokenChallenge, tokenRequest);
219     if (ret != HITLS_AUTH_SUCCESS) {
220         return ret;
221     }
222     HITLS_AUTH_PrivPassToken *output = HITLS_AUTH_PrivPassNewToken(HITLS_AUTH_PRIVPASS_TOKEN_REQUEST);
223     if (output == NULL) {
224         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
225         return BSL_MALLOC_FAIL;
226     }
227     uint8_t challengeDigest[PRIVPASS_TOKEN_SHA256_SIZE];
228     const PrivPass_TokenChallenge *challenge = tokenChallenge->st.tokenChallenge;
229     PrivPass_TokenRequest *request = output->st.tokenRequest;
230     uint32_t authenticatorLen = ObtainAuthenticatorLen(challenge->tokenType); // challenge->tokenType has been checked.
231     // Construct token_input = concat(token_type, nonce, challenge_digest, token_key_id)
232     uint8_t tokenInput[HITLS_AUTH_PRIVPASS_TOKEN_INPUT_LEN];
233     size_t offset = 0;
234     // Copy token type from challenge
235     request->tokenType = challenge->tokenType;
236     request->truncatedTokenKeyId = ctx->tokenKeyId[PRIVPASS_TOKEN_SHA256_SIZE - 1];
237     // cal tokenChallengeDigest
238     ret = GenerateChallengeDigest(ctx, tokenChallenge, challengeDigest);
239     if (ret != HITLS_AUTH_SUCCESS) {
240         BSL_ERR_PUSH_ERROR(ret);
241         goto ERR;
242     }
243     // Generate nonce
244     ret = ctx->method.random(ctx->nonce, PRIVPASS_TOKEN_NONCE_LEN);
245     if (ret != HITLS_AUTH_SUCCESS) {
246         BSL_ERR_PUSH_ERROR(ret);
247         goto ERR;
248     }
249 
250     // Add token type (2 bytes)
251     BSL_Uint16ToByte(challenge->tokenType, tokenInput);
252     offset += 2; // offset 2 bytes.
253     // Add nonce
254     (void)memcpy_s(tokenInput + offset, PRIVPASS_TOKEN_NONCE_LEN, ctx->nonce, PRIVPASS_TOKEN_NONCE_LEN);
255     offset += PRIVPASS_TOKEN_NONCE_LEN;
256     // Add challenge digest
257     (void)memcpy_s(tokenInput + offset, PRIVPASS_TOKEN_SHA256_SIZE, challengeDigest, PRIVPASS_TOKEN_SHA256_SIZE);
258     offset += PRIVPASS_TOKEN_SHA256_SIZE;
259     // Add token key id
260     (void)memcpy_s(tokenInput + offset, PRIVPASS_TOKEN_SHA256_SIZE, ctx->tokenKeyId, PRIVPASS_TOKEN_SHA256_SIZE);
261 
262     // Calculate blinded message
263     request->blindedMsg.data = BSL_SAL_Malloc(authenticatorLen);
264     if (request->blindedMsg.data == NULL) {
265         ret = BSL_MALLOC_FAIL;
266         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
267         goto ERR;
268     }
269     request->blindedMsg.dataLen = authenticatorLen;
270     ret = ctx->method.blind(ctx->pubKeyCtx, HITLS_AUTH_PRIVPASS_CRYPTO_SHA384, tokenInput,
271         HITLS_AUTH_PRIVPASS_TOKEN_INPUT_LEN, request->blindedMsg.data, &request->blindedMsg.dataLen);
272     if (ret != HITLS_AUTH_SUCCESS) {
273         BSL_ERR_PUSH_ERROR(ret);
274         goto ERR;
275     }
276 
277     *tokenRequest = output;
278     return HITLS_AUTH_SUCCESS;
279 ERR:
280     HITLS_AUTH_PrivPassFreeToken(output);
281     return ret;
282 }
283 
ParamCheckOfGenTokenResp(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenRequest,HITLS_AUTH_PrivPassToken ** tokenResponse)284 static int32_t ParamCheckOfGenTokenResp(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenRequest,
285     HITLS_AUTH_PrivPassToken **tokenResponse)
286 {
287     if (ctx == NULL || ctx->method.signData == NULL ||
288         tokenRequest == NULL || tokenRequest->type != HITLS_AUTH_PRIVPASS_TOKEN_REQUEST ||
289         tokenResponse == NULL || *tokenResponse != NULL) {
290         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
291         return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
292     }
293     if (tokenRequest->st.tokenRequest->tokenType != PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
294         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
295         return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
296     }
297 
298     if (ctx->prvKeyCtx == NULL) {
299         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_PRVKEY_INFO);
300         return HITLS_AUTH_PRIVPASS_NO_PRVKEY_INFO;
301     }
302     if (ctx->pubKeyCtx == NULL) {
303         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO);
304         return HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO;
305     }
306     return HITLS_AUTH_SUCCESS;
307 }
308 
HITLS_AUTH_PrivPassGenTokenResponse(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenRequest,HITLS_AUTH_PrivPassToken ** tokenResponse)309 int32_t HITLS_AUTH_PrivPassGenTokenResponse(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenRequest,
310     HITLS_AUTH_PrivPassToken **tokenResponse)
311 {
312     int32_t ret = ParamCheckOfGenTokenResp(ctx, tokenRequest, tokenResponse);
313     if (ret != HITLS_AUTH_SUCCESS) {
314         return ret;
315     }
316 
317     const PrivPass_TokenRequest *request = tokenRequest->st.tokenRequest;
318     uint32_t authenticatorLen = ObtainAuthenticatorLen(request->tokenType); // request->tokenType has been checked.
319     if (request->truncatedTokenKeyId != ctx->tokenKeyId[PRIVPASS_TOKEN_SHA256_SIZE - 1]) {
320         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_KEYID);
321         return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_KEYID;
322     }
323     if (request->blindedMsg.dataLen != authenticatorLen) {
324         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_BLINDED_MSG);
325         return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_BLINDED_MSG;
326     }
327     HITLS_AUTH_PrivPassToken *output = HITLS_AUTH_PrivPassNewToken(HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE);
328     if (output == NULL) {
329         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
330         return BSL_MALLOC_FAIL;
331     }
332     PrivPass_TokenResponse *response = output->st.tokenResponse;
333     response->type = HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE_PUB;
334     // Calculate blind signature
335     response->st.pubResp.blindSig = BSL_SAL_Malloc(authenticatorLen);
336     if (response->st.pubResp.blindSig == NULL) {
337         ret = BSL_MALLOC_FAIL;
338         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
339         goto ERR;
340     }
341     response->st.pubResp.blindSigLen = authenticatorLen;
342 
343     ret = ctx->method.signData(ctx->prvKeyCtx, request->blindedMsg.data, request->blindedMsg.dataLen,
344         response->st.pubResp.blindSig, &response->st.pubResp.blindSigLen);
345     if (ret != HITLS_AUTH_SUCCESS) {
346         BSL_ERR_PUSH_ERROR(ret);
347         goto ERR;
348     }
349     *tokenResponse = output;
350     return HITLS_AUTH_SUCCESS;
351 
352 ERR:
353     HITLS_AUTH_PrivPassFreeToken(output);
354     return ret;
355 }
356 
ParamCheckOfGenToken(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,const HITLS_AUTH_PrivPassToken * tokenResponse,HITLS_AUTH_PrivPassToken ** token)357 static int32_t ParamCheckOfGenToken(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
358     const HITLS_AUTH_PrivPassToken *tokenResponse, HITLS_AUTH_PrivPassToken **token)
359 {
360     if (ctx == NULL || ctx->method.unBlind == NULL ||
361         tokenChallenge == NULL || tokenChallenge->type != HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE ||
362         tokenResponse == NULL || tokenResponse->type != HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE ||
363         token == NULL || *token != NULL) {
364         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
365         return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
366     }
367     if (ctx->pubKeyCtx == NULL) {
368         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO);
369         return HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO;
370     }
371     if (tokenChallenge->st.tokenChallenge->tokenType == PRIVPASS_PUBLIC_VERIFY_TOKENTYPE &&
372         tokenResponse->st.tokenResponse->type == HITLS_AUTH_PRIVPASS_TOKEN_RESPONSE_PUB) {
373         return HITLS_AUTH_SUCCESS;
374     }
375     BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
376     return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
377 }
378 
HITLS_AUTH_PrivPassGenToken(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,const HITLS_AUTH_PrivPassToken * tokenResponse,HITLS_AUTH_PrivPassToken ** token)379 int32_t HITLS_AUTH_PrivPassGenToken(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
380     const HITLS_AUTH_PrivPassToken *tokenResponse, HITLS_AUTH_PrivPassToken **token)
381 {
382     int32_t ret = ParamCheckOfGenToken(ctx, tokenChallenge, tokenResponse, token);
383     if (ret != HITLS_AUTH_SUCCESS) {
384         return ret;
385     }
386 
387     HITLS_AUTH_PrivPassToken *output = HITLS_AUTH_PrivPassNewToken(HITLS_AUTH_PRIVPASS_TOKEN_INSTANCE);
388     if (output == NULL) {
389         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
390         return BSL_MALLOC_FAIL;
391     }
392     uint8_t challengeDigest[PRIVPASS_TOKEN_SHA256_SIZE];
393     PrivPass_TokenInstance *finalToken = output->st.token;
394     const PrivPass_TokenChallenge *challenge = tokenChallenge->st.tokenChallenge;
395     const PrivPass_TokenResponse *response = tokenResponse->st.tokenResponse;
396     uint32_t outputLen = ObtainAuthenticatorLen(challenge->tokenType);
397     // Copy token type from challenge
398     finalToken->tokenType = challenge->tokenType;
399     // cal tokenChallengeDigest
400     ret = GenerateChallengeDigest(ctx, tokenChallenge, challengeDigest);
401     if (ret != HITLS_AUTH_SUCCESS) {
402         BSL_ERR_PUSH_ERROR(ret);
403         goto ERR;
404     }
405     // Copy nonce from ctx
406     (void)memcpy_s(finalToken->nonce, PRIVPASS_TOKEN_NONCE_LEN, ctx->nonce, PRIVPASS_TOKEN_NONCE_LEN);
407 
408     // Copy challenge digest from ctx
409     (void)memcpy_s(finalToken->challengeDigest, PRIVPASS_TOKEN_SHA256_SIZE,
410         challengeDigest, PRIVPASS_TOKEN_SHA256_SIZE);
411 
412     // Copy token key ID from ctx
413     (void)memcpy_s(finalToken->tokenKeyId, PRIVPASS_TOKEN_SHA256_SIZE, ctx->tokenKeyId, PRIVPASS_TOKEN_SHA256_SIZE);
414 
415     // Copy authenticator from tokenResponse
416     finalToken->authenticator.data = BSL_SAL_Malloc(outputLen);
417     if (finalToken->authenticator.data == NULL) {
418         ret = BSL_MALLOC_FAIL;
419         BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
420         goto ERR;
421     }
422     ret = ctx->method.unBlind(ctx->pubKeyCtx, response->st.pubResp.blindSig, response->st.pubResp.blindSigLen,
423         finalToken->authenticator.data, &outputLen);
424     if (ret != HITLS_AUTH_SUCCESS) {
425         BSL_ERR_PUSH_ERROR(ret);
426         goto ERR;
427     }
428     finalToken->authenticator.dataLen = outputLen;
429     *token = output;
430     return HITLS_AUTH_SUCCESS;
431 
432 ERR:
433     HITLS_AUTH_PrivPassFreeToken(output);
434     return ret;
435 }
436 
ParamCheckOfVerifyToken(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,const HITLS_AUTH_PrivPassToken * token)437 static int32_t ParamCheckOfVerifyToken(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
438     const HITLS_AUTH_PrivPassToken *token)
439 {
440     if (ctx == NULL || ctx->method.verify == NULL ||
441         tokenChallenge == NULL || tokenChallenge->type != HITLS_AUTH_PRIVPASS_TOKEN_CHALLENGE ||
442         token == NULL || token->type != HITLS_AUTH_PRIVPASS_TOKEN_INSTANCE) {
443         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
444         return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
445     }
446     if (tokenChallenge->st.tokenChallenge->tokenType != token->st.token->tokenType) {
447         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
448         return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
449     }
450     if (tokenChallenge->st.tokenChallenge->tokenType != PRIVPASS_PUBLIC_VERIFY_TOKENTYPE) {
451         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE);
452         return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_TYPE;
453     }
454     if (ctx->pubKeyCtx == NULL) {
455         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO);
456         return HITLS_AUTH_PRIVPASS_NO_PUBKEY_INFO;
457     }
458     PrivPass_TokenInstance *finalToken = token->st.token;
459     if (memcmp(finalToken->tokenKeyId, ctx->tokenKeyId, PRIVPASS_TOKEN_SHA256_SIZE) != 0) {
460         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_KEYID);
461         return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_KEYID;
462     }
463     uint8_t challengeDigest[PRIVPASS_TOKEN_SHA256_SIZE];
464     int32_t ret = GenerateChallengeDigest(ctx, tokenChallenge, challengeDigest);
465     if (ret != HITLS_AUTH_SUCCESS) {
466         BSL_ERR_PUSH_ERROR(ret);
467         return ret;
468     }
469     if (memcmp(finalToken->challengeDigest, challengeDigest, PRIVPASS_TOKEN_SHA256_SIZE) != 0) {
470         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE_DIGEST);
471         return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_CHALLENGE_DIGEST;
472     }
473     return HITLS_AUTH_SUCCESS;
474 }
475 
HITLS_AUTH_PrivPassVerifyToken(HITLS_AUTH_PrivPassCtx * ctx,const HITLS_AUTH_PrivPassToken * tokenChallenge,const HITLS_AUTH_PrivPassToken * token)476 int32_t HITLS_AUTH_PrivPassVerifyToken(HITLS_AUTH_PrivPassCtx *ctx, const HITLS_AUTH_PrivPassToken *tokenChallenge,
477     const HITLS_AUTH_PrivPassToken *token)
478 {
479     int32_t ret = ParamCheckOfVerifyToken(ctx, tokenChallenge, token);
480     if (ret != HITLS_AUTH_SUCCESS) {
481         return ret;
482     }
483     PrivPass_TokenInstance *finalToken = token->st.token;
484     uint32_t authenticatorLen = ObtainAuthenticatorLen(finalToken->tokenType);
485     if (finalToken->authenticator.data == NULL || authenticatorLen != finalToken->authenticator.dataLen) {
486         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_TOKEN_INSTANCE);
487         return HITLS_AUTH_PRIVPASS_INVALID_TOKEN_INSTANCE;
488     }
489     // Construct token_input = concat(token_type, nonce, challenge_digest, token_key_id)
490     uint8_t tokenInput[HITLS_AUTH_PRIVPASS_TOKEN_INPUT_LEN];
491     size_t offset = 0;
492 
493     // Add token type (2 bytes)
494     BSL_Uint16ToByte(finalToken->tokenType, tokenInput);
495     offset += 2; // offset 2 bytes.
496 
497     // Add nonce
498     (void)memcpy_s(tokenInput + offset, PRIVPASS_TOKEN_NONCE_LEN, finalToken->nonce, PRIVPASS_TOKEN_NONCE_LEN);
499     offset += PRIVPASS_TOKEN_NONCE_LEN;
500 
501     // Add challenge digest
502     (void)memcpy_s(tokenInput + offset, PRIVPASS_TOKEN_SHA256_SIZE,
503         finalToken->challengeDigest, PRIVPASS_TOKEN_SHA256_SIZE);
504     offset += PRIVPASS_TOKEN_SHA256_SIZE;
505 
506     // Add token key id
507     (void)memcpy_s(tokenInput + offset, PRIVPASS_TOKEN_SHA256_SIZE, finalToken->tokenKeyId, PRIVPASS_TOKEN_SHA256_SIZE);
508 
509     // Verify the token using ctx's verify method
510     ret = ctx->method.verify(ctx->pubKeyCtx, HITLS_AUTH_PRIVPASS_CRYPTO_SHA384, tokenInput,
511         HITLS_AUTH_PRIVPASS_TOKEN_INPUT_LEN, finalToken->authenticator.data, PRIVPASS_TOKEN_NK);
512     if (ret != HITLS_AUTH_SUCCESS) {
513         BSL_ERR_PUSH_ERROR(ret);
514     }
515     return ret;
516 }
517 
HITLS_AUTH_PrivPassSetPubkey(HITLS_AUTH_PrivPassCtx * ctx,uint8_t * pki,uint32_t pkiLen)518 int32_t HITLS_AUTH_PrivPassSetPubkey(HITLS_AUTH_PrivPassCtx *ctx, uint8_t *pki, uint32_t pkiLen)
519 {
520     if (ctx == NULL || ctx->method.decodePubKey == NULL || ctx->method.freePkeyCtx == NULL ||
521         ctx->method.digest == NULL || pki == NULL || pkiLen == 0) {
522         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
523         return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
524     }
525     uint32_t tokenKeyIdLen = PRIVPASS_TOKEN_SHA256_SIZE;
526     void *pubKeyCtx = NULL;
527     int32_t ret = ctx->method.decodePubKey(NULL, NULL, pki, pkiLen, &pubKeyCtx);
528     if (ret != HITLS_AUTH_SUCCESS) {
529         BSL_ERR_PUSH_ERROR(ret);
530         return ret;
531     }
532     if (ctx->prvKeyCtx != NULL) {
533         if (ctx->method.checkKeyPair == NULL) {
534             BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_KEYPAIR_CHECK_CALLBACK);
535             ret = HITLS_AUTH_PRIVPASS_NO_KEYPAIR_CHECK_CALLBACK;
536             goto ERR;
537         }
538 
539         ret = ctx->method.checkKeyPair(pubKeyCtx, ctx->prvKeyCtx);
540         if (ret != HITLS_AUTH_SUCCESS) {
541             ret = HITLS_AUTH_PRIVPASS_CHECK_KEYPAIR_FAILED;
542             BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_CHECK_KEYPAIR_FAILED);
543             goto ERR;
544         }
545     }
546     ret = ctx->method.digest(NULL, NULL, HITLS_AUTH_PRIVPASS_CRYPTO_SHA256, pki, pkiLen, ctx->tokenKeyId,
547         &tokenKeyIdLen);
548     if (ret != HITLS_AUTH_SUCCESS) {
549         BSL_ERR_PUSH_ERROR(ret);
550         goto ERR;
551     }
552     if (ctx->pubKeyCtx != NULL) {
553         ctx->method.freePkeyCtx(ctx->pubKeyCtx);
554     }
555     ctx->pubKeyCtx = pubKeyCtx;
556     return HITLS_AUTH_SUCCESS;
557 
558 ERR:
559     ctx->method.freePkeyCtx(pubKeyCtx);
560     return ret;
561 }
562 
HITLS_AUTH_PrivPassSetPrvkey(HITLS_AUTH_PrivPassCtx * ctx,void * param,uint8_t * ski,uint32_t skiLen)563 int32_t HITLS_AUTH_PrivPassSetPrvkey(HITLS_AUTH_PrivPassCtx *ctx, void *param, uint8_t *ski, uint32_t skiLen)
564 {
565     if (ctx == NULL || ctx->method.decodePrvKey == NULL || ctx->method.freePkeyCtx == NULL ||
566         ski == NULL || skiLen == 0) {
567         BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_INVALID_INPUT);
568         return HITLS_AUTH_PRIVPASS_INVALID_INPUT;
569     }
570     void *prvKeyCtx = NULL;
571     int32_t ret = ctx->method.decodePrvKey(NULL, NULL, param, ski, skiLen, &prvKeyCtx);
572     if (ret != HITLS_AUTH_SUCCESS) {
573         BSL_ERR_PUSH_ERROR(ret);
574         return ret;
575     }
576     if (ctx->pubKeyCtx != NULL) {
577         if (ctx->method.checkKeyPair == NULL) {
578             BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_NO_KEYPAIR_CHECK_CALLBACK);
579             ret = HITLS_AUTH_PRIVPASS_NO_KEYPAIR_CHECK_CALLBACK;
580             goto ERR;
581         }
582         ret = ctx->method.checkKeyPair(ctx->pubKeyCtx, prvKeyCtx);
583         if (ret != HITLS_AUTH_SUCCESS) {
584             ret = HITLS_AUTH_PRIVPASS_CHECK_KEYPAIR_FAILED;
585             BSL_ERR_PUSH_ERROR(HITLS_AUTH_PRIVPASS_CHECK_KEYPAIR_FAILED);
586             goto ERR;
587         }
588     }
589     if (ctx->prvKeyCtx != NULL) {
590         ctx->method.freePkeyCtx(ctx->prvKeyCtx);
591     }
592     ctx->prvKeyCtx = prvKeyCtx;
593     return HITLS_AUTH_SUCCESS;
594 
595 ERR:
596     ctx->method.freePkeyCtx(prvKeyCtx);
597     return ret;
598 }
599