yum download --source strongswan
diff SPECS/mystrongswan.spec SPECS/strongswan.spec
52d51
< BuildRequires: tpm2-tss-devel
125c124
< --enable-tss-tss2 --enable-tpm \
---
> --with-tss=trousers \
288d286
< %{_libdir}/%{name}/plugins/lib%{name}-tpm.so
strongSwan 与 Openswan 都是 νρΝ 软件
安装主程序包
sudo apt-get install strongswan
安装扩展包, Ubunut 1704中包含支持TPM 2.0的插件
sudo apt-get install libstrongswan-extra-plugins
sudo apt-get install strongswan-pki
--enable-tss-tss2
enable TPM 2.0 TSS2 library, requires libtss2 library [ no ]. Since 5.5.0.
Documents of the usage of pki against tpm handles can be found at:
- https://wiki.strongswan.org/projects/strongswan/wiki/TpmPlugin
pki命令与TPM2.0相关的插件代码位于
https://github.com/strongswan/strongswan/blob/master/src/libtpmtss/tpm_tss_tss2.c
/**
* read the public key portion of a TSS 2.0 AIK key from NVRAM
*/
bool read_public(private_tpm_tss_tss2_t *this, TPMI_DH_OBJECT handle,
TPM2B_PUBLIC *public)
{
uint32_t rval;
TPM2B_NAME name = { { sizeof(TPM2B_NAME)-2, } };
TPM2B_NAME qualified_name = { { sizeof(TPM2B_NAME)-2, } };
TPMS_AUTH_RESPONSE session_data;
TSS2_SYS_RSP_AUTHS sessions_data;
TPMS_AUTH_RESPONSE *session_data_array[1];
session_data_array[0] = &session_data;
sessions_data.rspAuths = &session_data_array[0];
sessions_data.rspAuthsCount = 1;
/* read public key for a given object handle from TPM 2.0 NVRAM */
rval = Tss2_Sys_ReadPublic(this->sys_context, handle, 0, public, &name,
&qualified_name, &sessions_data);
if (rval != TPM_RC_SUCCESS)
{
DBG1(DBG_PTS, "%s could not read public key from handle 0x%08x: 0x%06x",
LABEL, handle, rval);
return FALSE;
}
return TRUE;
}
typedef chunk_t (*get_public_func_t)(tpm_tss_t *this, uint32_t handle);
static chunk_t _get_public(private_tpm_tss_tss2_t *this, uint32_t handle)
{
TPM2B_PUBLIC public = { { 0, } };
TPM_ALG_ID sig_alg, digest_alg;
chunk_t aik_blob, aik_pubkey = chunk_empty;
if (!read_public(this, handle, &public))
{
return chunk_empty;
}
aik_blob = chunk_create((u_char*)&public, sizeof(public));
DBG3(DBG_LIB, "%s AIK public key blob: %B", LABEL, &aik_blob);
/* convert TSS 2.0 AIK public key blot into PKCS#1 format */
switch (public.t.publicArea.type)
{
case TPM_ALG_RSA:
{
TPM2B_PUBLIC_KEY_RSA *rsa;
TPMT_RSA_SCHEME *scheme;
chunk_t aik_exponent, aik_modulus;
scheme = &public.t.publicArea.parameters.rsaDetail.scheme;
sig_alg = scheme->scheme;
digest_alg = scheme->details.anySig.hashAlg;
rsa = &public.t.publicArea.unique.rsa;
aik_modulus = chunk_create(rsa->t.buffer, rsa->t.size);
aik_exponent = chunk_from_chars(0x01, 0x00, 0x01);
/* subjectPublicKeyInfo encoding of AIK RSA key */
if (!lib->encoding->encode(lib->encoding, PUBKEY_SPKI_ASN1_DER,
NULL, &aik_pubkey, CRED_PART_RSA_MODULUS, aik_modulus,
CRED_PART_RSA_PUB_EXP, aik_exponent, CRED_PART_END))
{
DBG1(DBG_PTS, "%s subjectPublicKeyInfo encoding of AIK key "
"failed", LABEL);
}
break;
}
case TPM_ALG_ECC:
{
TPMS_ECC_POINT *ecc;
TPMT_ECC_SCHEME *scheme;
chunk_t ecc_point;
uint8_t *pos;
scheme = &public.t.publicArea.parameters.eccDetail.scheme;
sig_alg = scheme->scheme;
digest_alg = scheme->details.anySig.hashAlg;
ecc = &public.t.publicArea.unique.ecc;
/* allocate space for bit string */
pos = asn1_build_object(&ecc_point, ASN1_BIT_STRING,
2 + ecc->x.t.size + ecc->y.t.size);
/* bit string length is a multiple of octets */
*pos++ = 0x00;
/* uncompressed ECC point format */
*pos++ = 0x04;
/* copy x coordinate of ECC point */
memcpy(pos, ecc->x.t.buffer, ecc->x.t.size);
pos += ecc->x.t.size;
/* copy y coordinate of ECC point */
memcpy(pos, ecc->y.t.buffer, ecc->y.t.size);
/* subjectPublicKeyInfo encoding of AIK ECC key */
aik_pubkey = asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_wrap(ASN1_SEQUENCE, "mm",
asn1_build_known_oid(OID_EC_PUBLICKEY),
asn1_build_known_oid(ecc->x.t.size == 32 ?
OID_PRIME256V1 : OID_SECT384R1)),
ecc_point);
break;
}
default:
DBG1(DBG_PTS, "%s unsupported AIK key type", LABEL);
return chunk_empty;
}
DBG1(DBG_PTS, "AIK signature algorithm is %N with %N hash",
tpm_alg_id_names, sig_alg, tpm_alg_id_names, digest_alg);
return aik_pubkey;
}
extern get_public_func_t get_public = (get_public_func_t) _get_public;