cert.c
3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include "cert.h"
extern const BbRsaPublicKey4096 gRootKey;
extern const BbRsaExponent gRootExp;
int getCertSize(BbCertBase *cert)
{
#ifdef DEBUG
PRINT_LONG(cert->certType);
#endif
switch(cert->certType){
case BB_CERT_TYPE_BB:
return sizeof(BbEccCert);
case BB_CERT_TYPE_SERVER:
return sizeof(BbRsaCert);
default:
return SK_FAIL;
};
}
int getCertSigSize(BbCertBase *cert)
{
switch(cert->sigType){
case BB_SIG_TYPE_RSA2048:
case BB_SIG_TYPE_RSA4096:
return sizeof(BbGenericSig);
case BB_SIG_TYPE_ECC:
return sizeof(BbEccSig);
default:
return SK_FAIL;
};
}
int getCertSig(BbCertBase *cert,BbGenericSig **sig)
{
switch(cert->certType){
case BB_CERT_TYPE_BB:
*sig = &((BbEccCert *)cert)->signature;
break;
case BB_CERT_TYPE_SERVER:
*sig = &((BbRsaCert *)cert)->signature;
break;
default:
return SK_FAIL;
};
return SK_SUCCESS;
}
int verifyCertSig(BbCertBase *cert, BbCertBase *signer)
{
SkDataChain dataChain[1];
int certSize,certSigSize;
BbGenericSig *sig;
if(cert == NULL)
return SK_FAIL;
/* TODO: handle errors from these calls */
certSize = getCertSize(cert);
certSigSize = getCertSigSize(cert);
getCertSig(cert,&sig);
/* for certs, only one data chunk is needed */
dataChain[0].data = (u8 *)cert;
dataChain[0].size = certSize - certSigSize;
/* sanity check */
if(strcmp(cert->issuer,BB_CERT_STR_ROOT) != 0 && signer == NULL){
return SK_FAIL;
}
if(strcmp(cert->issuer,BB_CERT_STR_ROOT) == 0){
/* Root case, assume rsa 4096 sig type */
return verifyRsaSigDataChain(dataChain,1, (u32 *)gRootKey, gRootExp,
BB_SIG_TYPE_RSA4096,
sig);
}
switch(cert->sigType){
case BB_SIG_TYPE_RSA2048:
case BB_SIG_TYPE_RSA4096:
return verifyRsaSigDataChain(dataChain,1,
((BbRsaCert *)signer)->publicKey,
((BbRsaCert *)signer)->exponent,
cert->sigType,
sig);
/*
case BB_SIG_TYPE_ECC:
return verifyEccSig(dataChain,
((BbEccCert *)(signer))->publicKey,
cert->sigType,
sig);
*/
default:
return SK_FAIL;
}
}
int verifyCertChain(BbCertBase **chain, u32 chainType)
{
int i;
char *name = BB_CERT_STR_XS_PREFIX;
/*
* check type to insure, for example, a ticket server chain
* could not have been used to sign content. this way, ticket
* servers could not be used to sign sysapp cmdh. sufficient
* to check the CA in the path.
*
* NOTE: BbServerName definition in bbtypes.h fixes position of
* '-' chars.
*/
if(chainType != CHAIN_TYPE_DONT_CARE &&
chainType == CHAIN_TYPE_CONTENT_PUB){
name = BB_CERT_STR_CP_PREFIX;
}
for(i = 0; i < BB_CERT_CHAIN_MAXLEN; i++){
/* break out if it is last one */
if(chainType!=CHAIN_TYPE_DONT_CARE &&
strncmp(chain[i]->name.server,name,2) != 0){
return SK_FAIL;
}
if(strcmp(chain[i]->issuer,BB_CERT_STR_ROOT) == 0){
return verifyCertSig(chain[i], NULL);
}
if(verifyCertSig(chain[i], chain[i+1]) != SK_SUCCESS){
return SK_FAIL;
}
}
return SK_SUCCESS;
}