Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use X.509 certificate in CoAP communication #655

Closed
jas-singh14 opened this issue Jun 2, 2018 · 20 comments
Closed

How to use X.509 certificate in CoAP communication #655

jas-singh14 opened this issue Jun 2, 2018 · 20 comments

Comments

@jas-singh14
Copy link

We are using Californium library to establish CoAP communication between client and server using X.509 certificates (mutual authentication over DTLS).
Please help in pointing to the code flow that needs to be implemented on the server and client side to achieve this functionality.

@AlexITC
Copy link
Contributor

AlexITC commented Jun 2, 2018

What's the difference between this question and #652 ?

  • On the server, you set a certificate and its private key (this allows the server to decipher the traffic).
  • On the client, you add the server certificate as trusted, the certificate has a public key that is used to cipher the traffic.

If you want to use mutual authentication (let's say, the client has a certificate too), I can't say if that's possible with the latest californium version, we applied a couple of commits to allow client certificates, see californium-2.0.0-M5-Artik.

@jas-singh14
Copy link
Author

Hi Alexis,

Thanks for the information.
How can we be fully sure about mutual authentication?

@AlexITC
Copy link
Contributor

AlexITC commented Jun 2, 2018

As I said, I don't know remember how it works in the current californium, I think you register the trusted CAs on the server and when a client sends its certificate, the server validates that the certificate is signed by one of the trusted CAs.

On our fork, what we did is to defer this validation to a custom client certificate validator.

@vikram919
Copy link
Contributor

https://github.com/eclipse/californium/tree/2.0.x/demo-certs

I think above link in the project README, explains clearly how the server and client are mutually authenticated using the example key and trust stores provided by demo certs folder using self signed certificate from root CA or a chain of trust from intermediate CA

How can we be fully sure about mutual authentication?

I did not understand, what it means actually?

@jas-singh14
Copy link
Author

Vikram,

“ how can we be sure about mutual authentication” was in relation to Alexis point that he wasn’t sure if mutual authentication was supported in californium.
So my question was “ how can we be sure if mutual authentication is supported in californium “?
In case it is not supported, can this requirement be added to californium library?
Hope this clarifies...

@AlexITC
Copy link
Contributor

AlexITC commented Jun 2, 2018

I apologize to confuse you, mutual authentication is supported, since the time I was working with californium, there have been several improvements and I'm not sure how it works at the moment.

@vikram919
Copy link
Contributor

vikram919 commented Jun 3, 2018

@jas-singh14
I have already mentioned in #652 that mutual authention is implemented, tested and supported by californium.
There are several examples to demonstrate how it works, above duplicate issue you have raised there I have already written about cf-android example which show mutual authentication example
2. https://github.com/eclipse/californium/tree/2.0.x/demo-apps/cf-secure/src/main/java/org/eclipse/californium/examples cf-secure project also demonstrate it as well.

I also request you to refer to standard RFC 7252 about mutual authentication for CoAP.

@jas-singh14
Copy link
Author

We are using Californium and .Net library (https://github.com/Com-AugustCellars/CoAP-CSharp). However it seems that we are able to use the public keys from a self signed certificate from .Net library but such a functionality is not available in Californium. Can you please confirm this? and if possible suggest a workaround in californium. Basically our intention is that we should be able to use Californium in the same fashion as .Net library.
The way we have configured client and server using this .Net library is shown below:

  1. Server Code
    //Read Server Certificate
    X509Certificate2 x509 = ReadCertificate(@"ServerCert.cer");

//Initialize a object of Pre-Shared Key
PskOne = new OneKey();
PskOne.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
PskOne.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes(x509.PublicKey.Key.ToString())));
PskOne.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(x509.PublicKey.Key.ToString())));

UserKeys = new KeySet();
UserKeys.AddKey(PskOne);

//Initialize Coap Endpoint using userkey and Coaps port
CoAPEndPoint endpoint = new DTLSEndPoint(null, UserKeys, CoapsPort);

//Initialize CoapServer
CoapServer _server = new CoapServer();

_server.AddEndPoint(endpoint);
_server.Start();

  1. Client Code

//Read Client Certificate
X509Certificate2 x509 = ReadCertificate(@"ClientCert.cer");

//Initialize a object of Pre-Shared Key
PskOne = new OneKey();
PskOne.Add(CoseKeyKeys.KeyType, GeneralValues.KeyType_Octet);
PskOne.Add(CoseKeyKeys.KeyIdentifier, CBORObject.FromObject(Encoding.UTF8.GetBytes(x509.PublicKey.Key.ToString())));
PskOne.Add(CoseKeyParameterKeys.Octet_k, CBORObject.FromObject(Encoding.UTF8.GetBytes(x509.PublicKey.Key.ToString())));

//Initialize Coap Endpoint using userkey and Coaps port
DTLSClientEndPoint client = new DTLSClientEndPoint(PskOne);
client.Start();

@jas-singh14
Copy link
Author

Also in our understanding, private key is not required for certificate based authentication, So we are bit confused why Cf library is expecting that as one of the parameters (e.g. C# library mentioned above doesn't require private key). Can you please help here as well?

@sbernard31
Copy link
Contributor

You say that you C# library works just with a certificate without private key. But as far as I know, this does not make sense.
Look at the certificate wikipedia page
"In cryptography, a public key certificate, also known as a digital certificate or identity certificate, is an electronic document used to prove the ownership of a public key."

A public key must be used with a private key to be able to do asymetric cryptography.

If you are owner of those 2 certificates (ServerCert.cer and ClientCert.cer), you should also have the linked private keys as this is the first step to get your certificate :
"In the X.509 system, an organization that wants a signed certificate requests one via a certificate signing request (CSR).
To do this, it first generates a key pair, keeping the private key secret and using it to sign the CSR. "

(see https://en.wikipedia.org/wiki/X.509#Certificates)

@jas-singh14
Copy link
Author

Basically we want some clarification about why there is a need of specifying private key in Cf and not in
C# library:

we are using Cf API's below:
public Builder setIdentity(PrivateKey privateKey, PublicKey publicKey)
OR
public Builder setIdentity(PrivateKey privateKey, Certificate[] certificateChain, boolean preferRawPublicKeys)

@sbernard31
Copy link
Contributor

The real question is why the private key is not needed in the C# library...
As I explained above, this private key is needed to be able to do asymetric cryptography ... If there is no private key needed, anybody can just take your public certificate (as it is public...) and pretend to be you ...

@boaks
Copy link
Contributor

boaks commented Jun 4, 2018

@jas-singh14

If you want answers, maybe you provide a wireshark capture of your C# client using only a "public key".

//Initialize a object of Pre-Shared Key

smells, that something happens totally different than assumed :-).

And

Com-AugustCellars/CoAP-CSharp#46

seems also indicating, that x.509 is NOT working at all in the C# implementation your using.

@jimsch

If possible, could you check the above snippet, if it makes any sense to you?

@jas-singh14
Copy link
Author

I agree that private key is required for certificate generation. But is private key required during handshake between client and server is the prime question?

@AlexITC
Copy link
Contributor

AlexITC commented Jun 5, 2018

In asymmetric cryptography, you need the private and the public key, one key is used to cipher and the other one to decipher, if you provide a x509 certificate (it includes a public key) but not a private key, it is very likely that the traffic isn't being ciphered (assuming that your C# example works at all).

@boaks
Copy link
Contributor

boaks commented Jun 5, 2018

@jas-singh14

Are you now willing and able to provide a wireshark capture of your DTLS handshake of the C# implementation your using?

Are you understand, that the C# implementation your using doesn't support x.509 at all?
(Only a special branch provides you callbacks to implement it on your own.)

If you can't provide the capture nor understand the limitaion of the C# implementation your using, I assume, that your setup just uses the public key as PSK secret (according the comment in your snippet), or, as AlexITC wrote, doesn't use DTLS at all.

The wireshark capture will therefore show, that a "TLS_PSK_WITH_AES_128_???" is used in the SERVER_HELLO and not the "TLS_ECDHE_ECDSA_WITH_AES_128_???", or doesn't contain any valid DTLS records at all, because it doesn't use DTLS.

So without answers, I would like to close this issue and recommed that you use a other DTLS implementation (e.g. the one of java 9) to test your stuff!

@boaks
Copy link
Contributor

boaks commented Jun 5, 2018

I agree that private key is required for certificate generation. But is private key required during handshake between client and server is the prime question?

And the only answer will be the wireshark capture.

@sbernard31
Copy link
Contributor

I agree that private key is required for certificate generation. But is private key required during handshake between client and server is the prime question?

Yes ! Again if that was not the case anybody could just get your public certificate and usurp your identity ...

@boaks
Copy link
Contributor

boaks commented Jun 6, 2018

@jas-singh14

sorry, I didn't get it!
Is this issue now clear to you? So you agree on Simon's statement above, that you need both, the public and private key (which is also what I know)? Or do you still think, the C# sharp can do it without?

If you agree with Simon, and you also accept, that the C# implementation currently not supports certificates, could you then please make a final comment with that and close this issue?

@jas-singh14
Copy link
Author

Yes, I agree with the observations. Thanks all for the valuable inputs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants