Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
O
openconnect
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
mirror
openconnect
Commits
be3b4641
Commit
be3b4641
authored
Oct 12, 2018
by
David Woodhouse
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reinstate support for TPM2 'TSS2 KEY BLOB' support with GnuTLS
Signed-off-by:
David Woodhouse
<
dwmw2@infradead.org
>
parent
9f93019d
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
85 additions
and
17 deletions
+85
-17
gnutls.c
gnutls.c
+2
-1
gnutls.h
gnutls.h
+2
-1
gnutls_tpm2.c
gnutls_tpm2.c
+30
-8
gnutls_tpm2_esys.c
gnutls_tpm2_esys.c
+40
-2
gnutls_tpm2_ibm.c
gnutls_tpm2_ibm.c
+11
-5
No files found.
gnutls.c
View file @
be3b4641
...
...
@@ -1320,7 +1320,8 @@ static int load_certificate(struct openconnect_info *vpninfo)
}
/* Is it a PEM file with a TPM key blob? */
if
(
strstr
((
char
*
)
fdata
.
data
,
"-----BEGIN TSS2 PRIVATE KEY-----"
))
{
if
(
strstr
((
char
*
)
fdata
.
data
,
"-----BEGIN TSS2 PRIVATE KEY-----"
)
||
strstr
((
char
*
)
fdata
.
data
,
"-----BEGIN TSS2 KEY BLOB-----"
))
{
#ifndef HAVE_TSS2
vpn_progress
(
vpninfo
,
PRG_ERR
,
_
(
"This version of OpenConnect was built without TPM2 support
\n
"
));
...
...
gnutls.h
View file @
be3b4641
...
...
@@ -32,7 +32,8 @@ int load_tpm2_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
gnutls_privkey_t
*
pkey
,
gnutls_datum_t
*
pkey_sig
);
void
release_tpm2_ctx
(
struct
openconnect_info
*
info
);
int
install_tpm2_key
(
struct
openconnect_info
*
vpninfo
,
gnutls_privkey_t
*
pkey
,
gnutls_datum_t
*
pkey_sig
,
unsigned
int
parent
,
int
emptyauth
,
gnutls_datum_t
*
privdata
,
gnutls_datum_t
*
pubdata
);
unsigned
int
parent
,
int
emptyauth
,
int
legacy
,
gnutls_datum_t
*
privdata
,
gnutls_datum_t
*
pubdata
);
int
tpm2_rsa_sign_hash_fn
(
gnutls_privkey_t
key
,
gnutls_sign_algorithm_t
algo
,
void
*
_vpninfo
,
unsigned
int
flags
,
...
...
gnutls_tpm2.c
View file @
be3b4641
...
...
@@ -51,6 +51,21 @@ const asn1_static_node tpmkey_asn1_tab[] = {
{
NULL
,
0
,
NULL
}
};
const
asn1_static_node
tpmkey_asn1_tab_old
[]
=
{
{
"TPMKey"
,
536875024
,
NULL
},
{
NULL
,
1073741836
,
NULL
},
{
"TPMKey"
,
536870917
,
NULL
},
{
"type"
,
1073741836
,
NULL
},
{
"emptyAuth"
,
1610637316
,
NULL
},
{
NULL
,
2056
,
"0"
},
{
"parent"
,
1610637315
,
NULL
},
{
NULL
,
2056
,
"1"
},
{
"pubkey"
,
1610637319
,
NULL
},
{
NULL
,
2056
,
"2"
},
{
"privkey"
,
7
,
NULL
},
{
NULL
,
0
,
NULL
}
};
#if GNUTLS_VERSION_NUMBER < 0x030600
static
int
tpm2_rsa_sign_fn
(
gnutls_privkey_t
key
,
void
*
_vpninfo
,
...
...
@@ -168,16 +183,22 @@ int load_tpm2_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
int
emptyauth
=
0
;
unsigned
int
parent
;
int
err
,
ret
=
-
EINVAL
;
const
asn1_static_node
*
asn1tab
;
err
=
gnutls_pem_base64_decode_alloc
(
"TSS2 PRIVATE KEY"
,
fdata
,
&
asn1
);
if
(
err
)
{
vpn_progress
(
vpninfo
,
PRG_ERR
,
_
(
"Error decoding TSS2 key blob: %s
\n
"
),
gnutls_strerror
(
err
));
return
-
EINVAL
;
if
(
!
err
)
{
asn1tab
=
tpmkey_asn1_tab
;
}
else
{
if
(
gnutls_pem_base64_decode_alloc
(
"TSS2 KEY BLOB"
,
fdata
,
&
asn1
))
{
/* Report the first error */
vpn_progress
(
vpninfo
,
PRG_ERR
,
_
(
"Error decoding TSS2 key blob: %s
\n
"
),
gnutls_strerror
(
err
));
return
-
EINVAL
;
}
asn1tab
=
tpmkey_asn1_tab_old
;
}
err
=
asn1_array2tree
(
tpmkey_asn1_tab
,
&
tpmkey_def
,
NULL
);
err
=
asn1_array2tree
(
asn1tab
,
&
tpmkey_def
,
NULL
);
if
(
err
!=
ASN1_SUCCESS
)
{
vpn_progress
(
vpninfo
,
PRG_ERR
,
_
(
"Failed to create ASN.1 type for TPM2: %s
\n
"
),
...
...
@@ -243,7 +264,8 @@ int load_tpm2_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
/* Now we've extracted what we need from the ASN.1, invoke the
* actual TPM2 code (whichever implementation we end up with */
ret
=
install_tpm2_key
(
vpninfo
,
pkey
,
pkey_sig
,
parent
,
emptyauth
,
&
privdata
,
&
pubdata
);
ret
=
install_tpm2_key
(
vpninfo
,
pkey
,
pkey_sig
,
parent
,
emptyauth
,
asn1tab
==
tpmkey_asn1_tab_old
,
&
privdata
,
&
pubdata
);
if
(
ret
<
0
)
goto
out_tpmkey
;
...
...
gnutls_tpm2_esys.c
View file @
be3b4641
...
...
@@ -66,6 +66,7 @@ struct oc_tpm2_ctx {
TPM2B_DIGEST
ownerauth
;
unsigned
int
need_userauth
:
1
;
unsigned
int
need_ownerauth
:
1
;
unsigned
int
legacy_srk
:
1
;
unsigned
int
parent
;
};
...
...
@@ -106,6 +107,41 @@ static TPM2B_PUBLIC primaryTemplate = {
}
};
static
TPM2B_PUBLIC
primaryTemplate_legacy
=
{
.
publicArea
=
{
.
type
=
TPM2_ALG_ECC
,
.
nameAlg
=
TPM2_ALG_SHA256
,
.
objectAttributes
=
(
TPMA_OBJECT_USERWITHAUTH
|
TPMA_OBJECT_RESTRICTED
|
TPMA_OBJECT_DECRYPT
|
TPMA_OBJECT_NODA
|
TPMA_OBJECT_SENSITIVEDATAORIGIN
),
.
authPolicy
=
{
.
size
=
0
,
},
.
parameters
.
eccDetail
=
{
.
symmetric
=
{
.
algorithm
=
TPM2_ALG_AES
,
.
keyBits
.
aes
=
128
,
.
mode
.
aes
=
TPM2_ALG_CFB
,
},
.
scheme
=
{
.
scheme
=
TPM2_ALG_NULL
,
.
details
=
{}
},
.
curveID
=
TPM2_ECC_NIST_P256
,
.
kdf
=
{
.
scheme
=
TPM2_ALG_NULL
,
.
details
=
{}
},
},
.
unique
.
ecc
=
{
.
x
.
size
=
0
,
.
y
.
size
=
0
}
}
};
static
TPM2B_SENSITIVE_CREATE
primarySensitive
=
{
.
sensitive
=
{
.
userAuth
=
{
...
...
@@ -175,7 +211,8 @@ static int init_tpm2_primary(struct openconnect_info *vpninfo,
}
r
=
Esys_CreatePrimary
(
ctx
,
hierarchy
,
ESYS_TR_PASSWORD
,
ESYS_TR_NONE
,
ESYS_TR_NONE
,
&
primarySensitive
,
&
primaryTemplate
,
&
primarySensitive
,
vpninfo
->
tpm2
->
legacy_srk
?
&
primaryTemplate_legacy
:
&
primaryTemplate
,
&
allOutsideInfo
,
&
allCreationPCR
,
primaryHandle
,
NULL
,
NULL
,
NULL
,
NULL
);
if
(
r
==
KEY_AUTH_FAILED
)
{
...
...
@@ -480,7 +517,7 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
}
int
install_tpm2_key
(
struct
openconnect_info
*
vpninfo
,
gnutls_privkey_t
*
pkey
,
gnutls_datum_t
*
pkey_sig
,
unsigned
int
parent
,
int
emptyauth
,
gnutls_datum_t
*
privdata
,
gnutls_datum_t
*
pubdata
)
unsigned
int
parent
,
int
emptyauth
,
int
legacy
,
gnutls_datum_t
*
privdata
,
gnutls_datum_t
*
pubdata
)
{
TSS2_RC
r
;
...
...
@@ -517,6 +554,7 @@ int install_tpm2_key(struct openconnect_info *vpninfo, gnutls_privkey_t *pkey, g
}
vpninfo
->
tpm2
->
need_userauth
=
!
emptyauth
;
vpninfo
->
tpm2
->
legacy_srk
=
legacy
;
switch
(
vpninfo
->
tpm2
->
pub
.
publicArea
.
type
)
{
case
TPM2_ALG_RSA
:
return
GNUTLS_PK_RSA
;
...
...
gnutls_tpm2_ibm.c
View file @
be3b4641
...
...
@@ -40,6 +40,7 @@ struct oc_tpm2_ctx {
TPM2B_PRIVATE
priv
;
char
*
parent_pass
,
*
key_pass
;
unsigned
int
need_userauth
:
1
;
unsigned
int
legacy_srk
:
1
;
unsigned
int
parent
;
};
...
...
@@ -188,7 +189,8 @@ static void tpm2_flush_srk(TSS_CONTEXT *tssContext, TPM_HANDLE hSRK)
static
TPM_RC
tpm2_load_srk
(
TSS_CONTEXT
*
tssContext
,
TPM_HANDLE
*
h
,
const
char
*
auth
,
TPM_HANDLE
hierarchy
)
const
char
*
auth
,
TPM_HANDLE
hierarchy
,
int
legacy_srk
)
{
TPM_RC
rc
;
CreatePrimary_In
in
;
...
...
@@ -215,13 +217,15 @@ static TPM_RC tpm2_load_srk(TSS_CONTEXT *tssContext, TPM_HANDLE *h,
in
.
inPublic
.
publicArea
.
type
=
TPM_ALG_ECC
;
in
.
inPublic
.
publicArea
.
nameAlg
=
TPM_ALG_SHA256
;
in
.
inPublic
.
publicArea
.
objectAttributes
.
val
=
TPMA_OBJECT_FIXEDPARENT
|
TPMA_OBJECT_FIXEDTPM
|
TPMA_OBJECT_NODA
|
TPMA_OBJECT_SENSITIVEDATAORIGIN
|
TPMA_OBJECT_USERWITHAUTH
|
TPMA_OBJECT_DECRYPT
|
TPMA_OBJECT_RESTRICTED
;
if
(
!
legacy_srk
)
in
.
inPublic
.
publicArea
.
objectAttributes
.
val
|=
TPMA_OBJECT_FIXEDPARENT
|
TPMA_OBJECT_FIXEDTPM
;
in
.
inPublic
.
publicArea
.
parameters
.
eccDetail
.
symmetric
.
algorithm
=
TPM_ALG_AES
;
in
.
inPublic
.
publicArea
.
parameters
.
eccDetail
.
symmetric
.
keyBits
.
aes
=
128
;
in
.
inPublic
.
publicArea
.
parameters
.
eccDetail
.
symmetric
.
mode
.
aes
=
TPM_ALG_CFB
;
...
...
@@ -295,7 +299,7 @@ static TPM_HANDLE tpm2_load_key(struct openconnect_info *vpninfo, TSS_CONTEXT **
in
.
parentHandle
=
vpninfo
->
tpm2
->
parent
;
}
else
{
reauth_srk:
rc
=
tpm2_load_srk
(
tssContext
,
&
in
.
parentHandle
,
pass
,
vpninfo
->
tpm2
->
parent
);
rc
=
tpm2_load_srk
(
tssContext
,
&
in
.
parentHandle
,
pass
,
vpninfo
->
tpm2
->
parent
,
vpninfo
->
tpm2
->
legacy_srk
);
if
(
rc
==
KEY_AUTH_FAILED
)
{
free_pass
(
&
pass
);
if
(
!
request_passphrase
(
vpninfo
,
"openconnect_tpm2_hierarchy"
,
&
pass
,
...
...
@@ -511,7 +515,8 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo,
}
int
install_tpm2_key
(
struct
openconnect_info
*
vpninfo
,
gnutls_privkey_t
*
pkey
,
gnutls_datum_t
*
pkey_sig
,
unsigned
int
parent
,
int
emptyauth
,
gnutls_datum_t
*
privdata
,
gnutls_datum_t
*
pubdata
)
unsigned
int
parent
,
int
emptyauth
,
int
legacy
,
gnutls_datum_t
*
privdata
,
gnutls_datum_t
*
pubdata
)
{
TPM_RC
rc
;
BYTE
*
der
;
...
...
@@ -531,6 +536,7 @@ int install_tpm2_key(struct openconnect_info *vpninfo, gnutls_privkey_t *pkey, g
vpninfo
->
tpm2
->
parent
=
parent
;
vpninfo
->
tpm2
->
need_userauth
=
!
emptyauth
;
vpninfo
->
tpm2
->
legacy_srk
=
legacy
;
der
=
privdata
->
data
;
dersize
=
privdata
->
size
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment