zrf@debian:/tmp/sm2_cert$ openssl x509 -in sunCert.pem -text Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: SM2-with-SM3 Issuer: C=CN, O=zrf, CN=zrf CA Validity Not Before: Mar 30 08:13:17 2024 GMT Not After : Mar 30 08:13:17 2029 GMT Subject: C=CN, O=zrf, CN=zrf sun Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: 04:16:cf:b3:03:ec:6c:fb:c5:09:3d:97:e3:b8:2c: 0c:2c:9f:41:3a:ba:e2:d9:89:47:25:05:f3:88:d4: 89:77:ee:4a:d7:f7:80:a3:e7:4c:eb:68:a8:4a:75: 17:04:e4:8e:4e:24:b0:7d:9d:4f:b6:9d:27:86:be: 46:da:54:7a:61 ASN1 OID: SM2 X509v3 extensions: X509v3 Authority Key Identifier: 8A:12:AF:31:8E:83:B5:4B:2C:BB:B1:5D:DE:FC:4F:3B:63:A8:2A:F9 X509v3 Subject Alternative Name: IP Address:10.1.0.1 Signature Algorithm: SM2-with-SM3 Signature Value: 4f:88:b7:e0:00:f0:b9:8f:8c:72:74:fb:fd:97:20:72:98:2b: bd:a5:31:fa:eb:6b:ee:15:91:7b:9d:5b:8a:5e:3b:a8:0f:1c: 44:c9:f3:13:f6:13:c7:82:19:af:b7:ca:80:d6:1c:f0:07:d7: bd:17:9f:bd:45:70:25:c0:e2:d3 -----BEGIN CERTIFICATE----- MIIBeTCCASSgAwIBAgIBATAMBggqgRzPVQGDdQUAMCwxCzAJBgNVBAYTAkNOMQww CgYDVQQKEwN6cmYxDzANBgNVBAMTBnpyZiBDQTAeFw0yNDAzMzAwODEzMTdaFw0y OTAzMzAwODEzMTdaMC0xCzAJBgNVBAYTAkNOMQwwCgYDVQQKEwN6cmYxEDAOBgNV BAMTB3pyZiBzdW4wWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAQWz7MD7Gz7xQk9 l+O4LAwsn0E6uuLZiUclBfOI1Il37krX94Cj50zraKhKdRcE5I5OJLB9nU+2nSeG vkbaVHphozQwMjAfBgNVHSMEGDAWgBSKEq8xjoO1Syy7sV3e/E87Y6gq+TAPBgNV HREECDAGhwQKAQABMAwGCCqBHM9VAYN1BQADQQBPiLfgAPC5j4xydPv9lyBymCu9 pTH662vuFZF7nVuKXjuoDxxEyfMT9hPHghmvt8qA1hzwB9e9F5+9RXAlwOLT -----END CERTIFICATE-----
验证sun证书的合法性
1 2 3 4 5
zrf@debian:/tmp/sm2_cert$ pki -v -c caCert.pem -i sunCert.pem using certificate "C=CN, O=zrf, CN=zrf sun" using trusted ca certificate "C=CN, O=zrf, CN=zrf CA" reached self-signed root ca with a path length of 0 certificate trusted, lifetimes valid
zrf@debian:/tmp/sm2_cert$ pki -v -c caCert.pem -i moonCert.pem using certificate "C=CN, O=zrf, CN=zrf moon" using trusted ca certificate "C=CN, O=zrf, CN=zrf CA" reached self-signed root ca with a path length of 0 certificate trusted, lifetimes valid
sudo ip netns exec sun /usr/local/sbin/swanctl -q loaded certificate from '/etc/swanctl/x509/sunCert.pem' loaded certificate from '/etc/swanctl/x509ca/caCert.pem' loaded SM2 key from '/etc/swanctl/private/sunKey.pem' no authorities found, 0 unloaded no pools found, 0 unloaded loaded connection 'h2h' successfully loaded 1 connections, 0 unloaded
zrf@debian:~$ sudo ip netns exec sun /usr/local/sbin/swanctl -x
List of X.509 End Entity Certificates
subject: "C=CN, O=zrf, CN=zrf sun" issuer: "C=CN, O=zrf, CN=zrf CA" validity: not before Mar 30 16:13:17 2024, ok not after Mar 30 16:13:17 2029, ok (expires in 1825 days) serial: 01 altNames: 10.1.0.1 flags: authkeyId: 8a:12:af:31:8e:83:b5:4b:2c:bb:b1:5d:de:fc:4f:3b:63:a8:2a:f9 subjkeyId: 8c:8d:09:68:79:d1:71:d2:6f:78:fd:62:98:1b:7f:9b:92:dd:c7:9d pubkey: SM2 256 bits, has private key keyid: 67:ad:37:f5:6a:58:8c:ae:11:d9:ef:21:56:0b:5d:7f:0d:7f:8f:9a subjkey: 8c:8d:09:68:79:d1:71:d2:6f:78:fd:62:98:1b:7f:9b:92:dd:c7:9d
List of X.509 CA Certificates
subject: "C=CN, O=zrf, CN=zrf CA" issuer: "C=CN, O=zrf, CN=zrf CA" validity: not before Mar 30 16:01:08 2024, ok not after Mar 30 16:01:08 2034, ok (expires in 3651 days) serial: 55:43:e9:a5:8d:dd:c9:c7 flags: CA CRLSign self-signed subjkeyId: 8a:12:af:31:8e:83:b5:4b:2c:bb:b1:5d:de:fc:4f:3b:63:a8:2a:f9 pubkey: SM2 256 bits keyid: e8:56:19:cf:d3:ec:b7:1e:2e:fc:78:d5:e7:ef:22:8a:dd:f1:53:3b subjkey: 8a:12:af:31:8e:83:b5:4b:2c:bb:b1:5d:de:fc:4f:3b:63:a8:2a:f9 zrf@debian:~$
zrf@debian:~$ sudo ip netns exec moon /usr/local/sbin/swanctl -q loaded certificate from '/etc/swanctl/x509/moonCert.pem' loaded certificate from '/etc/swanctl/x509ca/caCert.pem' loaded SM2 key from '/etc/swanctl/private/moonKey.pem' no authorities found, 0 unloaded no pools found, 0 unloaded loaded connection 'h2h' successfully loaded 1 connections, 0 unloaded zrf@debian:~$ zrf@debian:~$ zrf@debian:~$ zrf@debian:~$ sudo ip netns exec moon /usr/local/sbin/swanctl -x
List of X.509 End Entity Certificates
subject: "C=CN, O=zrf, CN=zrf moon" issuer: "C=CN, O=zrf, CN=zrf CA" validity: not before Mar 30 16:19:06 2024, ok not after Mar 30 16:19:06 2029, ok (expires in 1825 days) serial: 02 altNames: 10.1.0.2 flags: authkeyId: 8a:12:af:31:8e:83:b5:4b:2c:bb:b1:5d:de:fc:4f:3b:63:a8:2a:f9 subjkeyId: c2:21:56:d6:6f:19:e0:75:4f:95:7e:1a:0f:2a:d2:66:29:2a:5a:cc pubkey: SM2 256 bits, has private key keyid: d7:b6:df:86:cf:dd:42:c5:1f:7b:64:c9:2e:a0:29:bb:f5:56:aa:aa subjkey: c2:21:56:d6:6f:19:e0:75:4f:95:7e:1a:0f:2a:d2:66:29:2a:5a:cc
List of X.509 CA Certificates
subject: "C=CN, O=zrf, CN=zrf CA" issuer: "C=CN, O=zrf, CN=zrf CA" validity: not before Mar 30 16:01:08 2024, ok not after Mar 30 16:01:08 2034, ok (expires in 3651 days) serial: 55:43:e9:a5:8d:dd:c9:c7 flags: CA CRLSign self-signed subjkeyId: 8a:12:af:31:8e:83:b5:4b:2c:bb:b1:5d:de:fc:4f:3b:63:a8:2a:f9 pubkey: SM2 256 bits keyid: e8:56:19:cf:d3:ec:b7:1e:2e:fc:78:d5:e7:ef:22:8a:dd:f1:53:3b subjkey: 8a:12:af:31:8e:83:b5:4b:2c:bb:b1:5d:de:fc:4f:3b:63:a8:2a:f9
zrf@debian:~$ sudo ip netns exec moon /usr/local/sbin/swanctl -i -i h2h [IKE] initiating Main Mode IKE_SA h2h[3] to 10.1.0.1 [ENC] generating ID_PROT request 0 [ SA V V V V V ] [NET] sending packet: from 10.1.0.2[500] to 10.1.0.1[500] (176 bytes) [NET] received packet: from 10.1.0.1[500] to 10.1.0.2[500] (156 bytes) [ENC] parsed ID_PROT response 0 [ SA V V V V ] [IKE] received XAuth vendor ID [IKE] received DPD vendor ID [IKE] received FRAGMENTATION vendor ID [IKE] received NAT-T (RFC 3947) vendor ID [CFG] selected proposal: IKE:SM4_CBC/HMAC_SM3/PRF_HMAC_SM3/CURVE_SM2 [ENC] generating ID_PROT request 0 [ KE No NAT-D NAT-D ] [NET] sending packet: from 10.1.0.2[500] to 10.1.0.1[500] (204 bytes) [NET] received packet: from 10.1.0.1[500] to 10.1.0.2[500] (255 bytes) [ENC] parsed ID_PROT response 0 [ KE No CERTREQ NAT-D NAT-D ] [IKE] received cert request for'C=CN, O=zrf, CN=zrf CA' [IKE] sending cert request for"C=CN, O=zrf, CN=zrf CA" [IKE] authentication of 'C=CN, O=zrf, CN=zrf moon' (myself) successful [IKE] sending end entity cert "C=CN, O=zrf, CN=zrf moon" [ENC] generating ID_PROT request 0 [ ID CERT SIG CERTREQ N(INITIAL_CONTACT) ] [NET] sending packet: from 10.1.0.2[500] to 10.1.0.1[500] (620 bytes) [NET] received packet: from 10.1.0.1[500] to 10.1.0.2[500] (540 bytes) [ENC] parsed ID_PROT response 0 [ ID CERT SIG ] [IKE] received end entity cert "C=CN, O=zrf, CN=zrf sun" [CFG] using certificate "C=CN, O=zrf, CN=zrf sun" [CFG] using trusted ca certificate "C=CN, O=zrf, CN=zrf CA" [CFG] reached self-signed root ca with a path length of 0 [CFG] checking certificate status of "C=CN, O=zrf, CN=zrf sun" [CFG] certificate status is not available [IKE] authentication of 'C=CN, O=zrf, CN=zrf sun' with SM2_WITH_SM2 successful [IKE] IKE_SA h2h[3] established between 10.1.0.2[C=CN, O=zrf, CN=zrf moon]...10.1.0.1[C=CN, O=zrf, CN=zrf sun] [IKE] scheduling rekeying in 14089s [IKE] maximum IKE_SA lifetime 15529s initiate completed successfully
/** * Implementation of a key exchange algorithms (e.g. Diffie-Hellman). */ structkey_exchange_t {
/** * Returns the shared secret of this key exchange method. * * @param secret shared secret (allocated) * @return TRUE if shared secret computed successfully */ bool (*get_shared_secret)(key_exchange_t *this, chunk_t *secret) __attribute__((warn_unused_result));
/** * Sets the public key from the peer. * * @note This operation should be relatively quick. Costly public key * validation operations or key derivation should be implemented in * get_shared_secret(). * * @param value public key of peer * @return TRUE if other public key verified and set */ bool (*set_public_key)(key_exchange_t *this, chunk_t value) __attribute__((warn_unused_result));
/** * Gets the own public key to transmit. * * @param value public key (allocated) * @return TRUE if public key retrieved */ bool (*get_public_key)(key_exchange_t *this, chunk_t *value) __attribute__((warn_unused_result));
/* 获取到签名的载荷 */ sig = sig_payload->get_hash(sig_payload); auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE); enumerator = lib->credmgr->create_public_enumerator(lib->credmgr, this->type, id, auth, TRUE); while (enumerator->enumerate(enumerator, &public, ¤t_auth)) { /* 使用信任的公钥进行验签 */ if (public->verify(public, scheme, NULL, hash, sig) && is_compliant_cert(current_auth)) { DBG1(DBG_IKE, "authentication of '%Y' with %N successful", id, signature_scheme_names, scheme); status = SUCCESS; auth->merge(auth, current_auth, FALSE); auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY); break; } }
return status; }
6.4 如何获得对端的公钥
在验证签名的时候我们可以发现,将使用对端的公钥进行验签,这个公钥就是通过证书请求获得的。
但是并不是随便的证书都可行,他需要被CA来验证。
我们可以看以下log:
1 2 3 4 5 6 7 8 9
12[CFG1] <h2h|3> using certificate "C=CN, O=zrf, CN=zrf moon" 12[CFG2] <h2h|3> certificate "C=CN, O=zrf, CN=zrf moon" key: 256 bit SM2 12[CFG1] <h2h|3> using trusted ca certificate "C=CN, O=zrf, CN=zrf CA" 12[CFG2] <h2h|3> certificate "C=CN, O=zrf, CN=zrf CA" key: 256 bit SM2 12[CFG1] <h2h|3> reached self-signed root ca with a path length of 0 12[CFG1] <h2h|3> checking certificate status of "C=CN, O=zrf, CN=zrf moon" 12[CFG2] <h2h|3> ocsp check skipped, no ocsp found 12[CFG1] <h2h|3> certificate status is not available 12[IKE1] <h2h|3> authentication of 'C=CN, O=zrf, CN=zrf moon' with SM2_WITH_SM2 successful