CESNET / netopeer2

NETCONF toolset
BSD 3-Clause "New" or "Revised" License
296 stars 187 forks source link

Server remains TLS-connecting with old <keystore-reference> even after it had been changed #1454

Closed alanik99 closed 11 months ago

alanik99 commented 11 months ago

Hello, team!

I'm changing in ietf-netconf-server module <keystore-reference>: changing <asymmetric-key> and <certificate> (tried both in startup and running datastores), - but after that, it connects (via TLS) both with old and new server key/cert. Restarting netopeer doesn't help. Is it a bug?

What I mean - <keystore-reference> in ietf-netconf-server module:

-- Regards, Alexander

michalvasko commented 11 months ago

I have briefly tested it and it worked as I expected.

it connects (via TLS) both with old and new server key/cert

What does that mean, with "both"?

alanik99 commented 11 months ago

I mean that it connects with an old one. But it should not, right? (after <keystore-reference> had been changed to new)

michalvasko commented 11 months ago

That is what I tested and the other certificate has been requested from sysrepo and used. Can you mention how exactly have you modified your configuration? What versions of the projects are you using?

alanik99 commented 11 months ago

In requests I've sent, new CA, client and server keys/certificates are created, I also change <fingerprint> to one from the new CA and <keystore-reference> to new server cert and key:

<?xml version="1.0" encoding="utf-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" 
     xmlns:ks="urn:ietf:params:xml:ns:yang:ietf-keystore" 
     message-id="1">
  <edit-config>
    <target>
      <running/>
    </target>
    <config>
      <keystore xmlns="urn:ietf:params:xml:ns:yang:ietf-keystore">
        <asymmetric-keys>
          <asymmetric-key>
            <name>serverkey-new</name>
            <algorithm>rsa2048</algorithm>
            <public-key>...new-serverpubkey...</public-key>
            <private-key>...new-serverprivkey...</private-key>
            <certificates>
              <certificate>
                <name>servercert-new</name>
                <cert>...new-servercert...</cert>
              </certificate>
            </certificates>
          </asymmetric-key>
        </asymmetric-keys>
      </keystore>
    </config>
  </edit-config>
</rpc>
<?xml version="1.0" encoding="utf-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" 
     xmlns:ts="urn:ietf:params:xml:ns:yang:ietf-truststore" 
     message-id="1">
  <edit-config>
    <target>
      <running/>
    </target>
    <config>
      <truststore xmlns="urn:ietf:params:xml:ns:yang:ietf-truststore">
<certificates>
      <name>clientcerts</name>
      <certificate>
        <name>clientcert-new</name>
        <cert>...new-clientcert...</cert>
      </certificate>
    </certificates>
    <certificates>
      <name>cacerts</name>
      <certificate>
        <name>cacert-new</name>
        <cert>...new-cacert...</cert>
      </certificate>
    </certificates>
      </truststore>
    </config>
  </edit-config>
</rpc>
<?xml version="1.0" encoding="utf-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" 
     xmlns:ncs="urn:ietf:params:xml:ns:yang:ietf-netconf-server" 
     message-id="1">
  <edit-config>
    <target>
      <running/>
    </target>
    <config>
      <netconf-server xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-server">
        <listen>
          <endpoint>
            <name>default-tls</name>
            <tls>
              <tls-server-parameters>
                <client-authentication>
                  <cert-maps>
                    <cert-to-name>
                      <id>1</id>
                      <fingerprint>02:...new-CA-fingerprint...</fingerprint>
                    </cert-to-name>
                  </cert-maps>
                </client-authentication>
              </tls-server-parameters>
            </tls>
          </endpoint>
        </listen>
      </netconf-server>
    </config>
  </edit-config>
</rpc>
<?xml version="1.0" encoding="utf-8"?>
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"
     xmlns:ncs="urn:ietf:params:xml:ns:yang:ietf-netconf-server"
     message-id="1">
  <edit-config>
    <target>
      <running/>
    </target>
    <config>
      <netconf-server xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-server">
        <listen>
          <endpoint>
            <name>default-tls</name>
            <tls>
              <tls-server-parameters>
                <server-identity>
                  <keystore-reference>
                    <asymmetric-key>serverkey-new</asymmetric-key>
                    <certificate>servercert-new</certificate>
                  </keystore-reference>
                </server-identity>
              </tls-server-parameters>
            </tls>
          </endpoint>
        </listen>
      </netconf-server>
    </config>
  </edit-config>
</rpc>

Packages versions I use:

michalvasko commented 11 months ago

The versions you are using are quite old but I am not sure there is anything relevant different in the current versions. But how exactly do you know the old certificates are used? And why are you changing cert-to-name? It is used only for client certificate username resolution, you are changing the server certificate.

alanik99 commented 11 months ago

That is what I tested and the other certificate has been requested from sysrepo and used. Can you mention how exactly have you modified your configuration? What versions of the projects are you using?

If I understand you correctly, it should continue connecting with an old client certificate even after <keystore-reference> had been changed to new server cert/key?

michalvasko commented 11 months ago

Well, yes, the client certificate should be the same because the client has not changed it, you have changed only the server certificate, which is presented to the client but no special verification is performed on it.

alanik99 commented 11 months ago

But how exactly do you know the old certificates are used?

Because it continues connecting with old client certificate, but new generated certificates and keys (CA, client and server) were added, and client continues connecting with it's old certificate, despite of server cert/key keystore-reference was changed

And why are you changing cert-to-name? It is used only for client certificate username resolution, you are changing the server certificate.

Not quite, I'm changing not only server certifiacate, but generate new CA, new client, new server keys/certs and add all them to the device

michalvasko commented 11 months ago

So what exactly is the behavior you assume wrong, you change all the certificates and cert-to-name and you are able to connect with a client? What client are you using?

alanik99 commented 11 months ago

I haven't changed, but added new ones remaining the old ones (I've mistaken, I've changed only keystore-reference, not cert-to-name, - I added new cert-to-name and remained old, so in the above message in request I remembered - I added it with <id>2</id>)

I just thought it's a bug that if you change keystore-reference to new server cert/key, it remains to connect with old client cert (While on the device both old and new CA, client, server key/certs are presented in sysrepo stores, changed only keystore-reference to new)

Using MGSOFT-Browser

alanik99 commented 11 months ago

So actually my question can be rephrased as: "Will the other server keys/certs (signed with for example CA1) work to connect with the other client key/cert (signed with the same CA1), if in <keystore-reference> we picked only one server key/cert, whose CA-signature (for example CA2) differs from the client cert/key's (CA1) which we use to connect ?"

It connects this way and I assume this is wrong, I suppose it shouldn't connect with CA1-signed client key/cert and CA2-signed server key/cert

michalvasko commented 11 months ago

Are you assuming that the server certificate must be signed by the same CA that the client certificate? Because it does not. If not then I still do not understand your question.

alanik99 commented 11 months ago

Are you assuming that the server certificate must be signed by the same CA that the client certificate?

Yes, I am. Ok, then could you tell me for which purpose is <keystore-reference>?

michalvasko commented 11 months ago

Well, you may want to read some TLS-related RFC to understand that. But most importantly, the presented certificate is used for encryption itself by the client because only the server has the private key to decrypt the data. And general validation is still performed by the client (such as that the certificate is properly signed by a trusted CA, that it is not expired or even revoked). Additionally, the server certificate must include the domain name in some form and if it does not match the hostname the client is connecting to, the client will terminate the connection.

MuteSpirit commented 11 months ago

Hi @alanik99 ,

From ietf-tls-server@2019-07-02.yang:

  grouping tls-server-grouping {                                    
    ....
    container server-identity {                                      
      nacm:default-deny-write;                                  
      description                                                  
        "A locally-defined or referenced end-entity certificate, 
         including any configured intermediate certificates, the
         TLS server will present when establishing a TLS connection
         in its Certificate message, as defined in Section 7.4.2
         in RFC 5246."; 
     ...
uses ks:local-or-keystore-end-entity-cert-with-key-grouping;  <<< <keystore-reference> is used inside this grouping
}

So if i correctly understand the say netopeer what server key+cert to use for incoming TLS connections. Theoretically netopeer server will send that certificate in ServerHello message during TLS connection establish procedure

alanik99 commented 11 months ago

Hello!

Yes, sorry, I was wrong, it works as expected.

Server sends correct certificate in "ServerHello" message during handshake. I've noticed this by different "commonName" property from server certificate, which server provided in "ServerHello" when I changed <keystore-reference> to another cert with another "commonName".

This was just the client (MGSOFT-Browser) who had both different CAs imported into it, so client could validate both server certs signed with different CAs.