This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

changing certificate in https_client sample

I am trying the https_client sample and I can get it to work unchanged. 

But I would like to connect to a different site than www.example.com. 

As far as I can understand what I need to do is:

change "example.com" in the HTTP_HEAD to another site (i've tried "vecka.nu")

#define HTTP_HEAD                                                              \
	"HEAD / HTTP/1.1\r\n"                                                  \
	"Host: vecka.nu:443\r\n"                                            \
	"Connection: close\r\n\r\n"

change "example.com" in the gettaddrinfo() call to another site (i've tried "vecka.nu"

	err = getaddrinfo("vecka.nu", NULL, &hints, &res);
	if (err) {
		printk("getaddrinfo() failed, err %d\n", errno);
		return;
	}

change the certificate used to one that works with the new site:

static const char cert[] = {
	//#include "../cert/DigiCertGlobalRootCA.pem"
	#include "../cert/vecka.cer"
};

I got the new certificate by visiting www.vecka.nu in chrome,

  • clicking the lock to the left of the address bar,
  • selecting certificate
  • going to the Details tab
  • clicking the Copy to File... button
  • selecting Base-64 encoded x.509 (.CER)
  • saving the file in the cert folder of the https_client sample
  • adding " to the beginning of each line and \n" to the end of each line in the new .cer file

"-----BEGIN CERTIFICATE-----\n"
"MIIFIzCCBAugAwIBAgISBDyCXR6TuWHUHlrrOBfKHRrQMA0GCSqGSIb3DQEBCwUA\n"
"MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD\n"

...
...

"DqGgSg+/716RXuzlHZqyb8pqU0cTTq2ojWgLx1FdDyfVcXGU6jOSeQ4WG2d8KJQ1\n"
"f0FUcInSAoWkuB8oWMFepQQxAxDdfj0=\n"
"-----END CERTIFICATE-----\n"

When I do this I get this output:

*** Booting Zephyr OS build v2.6.0-rc1-ncs1  ***
HTTPS client sample started
Provisioning certificate
Waiting for network.. OK
Connecting to example.com
connect() failed, err: 111

I also followed the same procedure to download the certificate from www.example.com in chrome, and noticed that the certificate did not match the certificate that came with the sample, so I suspect that I am not using the correct certificate.

How should I obtain the certificate for different websites?

Parents
  • Hello,

    I tried copying the setsockopt into the tls_setup() as you said, but I still got the same error

    int tls_setup(int fd)
    {
    	int err;
    	int verify;
    
    	/* Security tag that we have provisioned the certificate with */
    	const sec_tag_t tls_sec_tag[] = {
    		TLS_SEC_TAG,
    	};
    
    	/* Set up TLS peer verification */
    	enum {
    		NONE = 0,
    		OPTIONAL = 1,
    		REQUIRED = 2,
    	};
    
    	verify = REQUIRED;
    
    	err = setsockopt(fd, SOL_TLS, TLS_HOSTNAME, "vecka.nu", sizeof("vecka.nu"));
    	if (err) {
    		printk("Failed to setup TLS sec tag, err %d\n", errno);
    		return err;
    	}
    
    	err = setsockopt(fd, SOL_TLS, TLS_PEER_VERIFY, &verify, sizeof(verify));
    	if (err) {
    		printk("Failed to setup peer verification, err %d\n", errno);
    		return err;
    	}
    
    	/* Associate the socket with the security tag
    	 * we have provisioned the certificate with.
    	 */
    	err = setsockopt(fd, SOL_TLS, TLS_SEC_TAG_LIST, tls_sec_tag,
    			 sizeof(tls_sec_tag));
    	if (err) {
    		printk("Failed to setup TLS sec tag, err %d\n", errno);
    		return err;
    	}
    	return 0;
    }

    *** Booting Zephyr OS build v2.6.0-rc1-ncs1  ***
    HTTPS client sample started
    Provisioning certificate
    Waiting for network.. OK
    Connecting to example.com
    connect() failed, err: 111

    Thank you for the terminal command, it is much simpler than using a web browser.

    //Anna

Reply
  • Hello,

    I tried copying the setsockopt into the tls_setup() as you said, but I still got the same error

    int tls_setup(int fd)
    {
    	int err;
    	int verify;
    
    	/* Security tag that we have provisioned the certificate with */
    	const sec_tag_t tls_sec_tag[] = {
    		TLS_SEC_TAG,
    	};
    
    	/* Set up TLS peer verification */
    	enum {
    		NONE = 0,
    		OPTIONAL = 1,
    		REQUIRED = 2,
    	};
    
    	verify = REQUIRED;
    
    	err = setsockopt(fd, SOL_TLS, TLS_HOSTNAME, "vecka.nu", sizeof("vecka.nu"));
    	if (err) {
    		printk("Failed to setup TLS sec tag, err %d\n", errno);
    		return err;
    	}
    
    	err = setsockopt(fd, SOL_TLS, TLS_PEER_VERIFY, &verify, sizeof(verify));
    	if (err) {
    		printk("Failed to setup peer verification, err %d\n", errno);
    		return err;
    	}
    
    	/* Associate the socket with the security tag
    	 * we have provisioned the certificate with.
    	 */
    	err = setsockopt(fd, SOL_TLS, TLS_SEC_TAG_LIST, tls_sec_tag,
    			 sizeof(tls_sec_tag));
    	if (err) {
    		printk("Failed to setup TLS sec tag, err %d\n", errno);
    		return err;
    	}
    	return 0;
    }

    *** Booting Zephyr OS build v2.6.0-rc1-ncs1  ***
    HTTPS client sample started
    Provisioning certificate
    Waiting for network.. OK
    Connecting to example.com
    connect() failed, err: 111

    Thank you for the terminal command, it is much simpler than using a web browser.

    //Anna

Children
  • Hi Anna,

     

    diff --git a/samples/nrf9160/https_client/src/main.c b/samples/nrf9160/https_client/src/main.c
    index 509aacb96..7f85fd630 100644
    --- a/samples/nrf9160/https_client/src/main.c
    +++ b/samples/nrf9160/https_client/src/main.c
    @@ -17,9 +17,11 @@
     
     #define HTTPS_PORT 443
     
    +#define HTTPS_HOSTNAME "vecka.nu"
    +
     #define HTTP_HEAD                                                              \
     	"HEAD / HTTP/1.1\r\n"                                                  \
    -	"Host: example.com:443\r\n"                                            \
    +	"Host: " HTTPS_HOSTNAME ":443\r\n"                                     \
     	"Connection: close\r\n\r\n"
     
     #define HTTP_HEAD_LEN (sizeof(HTTP_HEAD) - 1)
    @@ -34,7 +36,7 @@ static char recv_buf[RECV_BUF_SIZE];
     
     /* Certificate for `example.com` */
     static const char cert[] = {
    -	#include "../cert/DigiCertGlobalRootCA.pem"
    +	#include "../cert/lets-encrypt-r3"
     };
     
     BUILD_ASSERT(sizeof(cert) < KB(4), "Certificate too large");
    @@ -137,6 +139,11 @@ int tls_setup(int fd)
     		return err;
     	}
     
    +	err = setsockopt(fd, SOL_TLS, TLS_HOSTNAME, HTTPS_HOSTNAME, sizeof(HTTPS_HOSTNAME) - 1);
    +	if (err) {
    +		printk("Failed to setup TLS hostname, err %d\n", errno);
    +		return err;
    +	}
     	return 0;
     }
     
    @@ -181,7 +188,7 @@ void main(void)
     	}
     	printk("OK\n");
     
    -	err = getaddrinfo("example.com", NULL, &hints, &res);
    +	err = getaddrinfo(HTTPS_HOSTNAME, NULL, &hints, &res);
     	if (err) {
     		printk("getaddrinfo() failed, err %d\n", errno);
     		return;
    @@ -201,7 +208,7 @@ void main(void)
     		goto clean_up;
     	}
     
    -	printk("Connecting to %s\n", "example.com");
    +	printk("Connecting to %s\n", HTTPS_HOSTNAME);
     	err = connect(fd, res->ai_addr, sizeof(struct sockaddr_in));
     	if (err) {
     		printk("connect() failed, err: %d\n", errno);
    

     

    And here's the lets-encrypt-r3 (signed by X1) in C form:

    "-----BEGIN CERTIFICATE-----\n" \
    "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\n" \
    "nLRbwHOoq7hHwg==\n" \
    "-----END CERTIFICATE-----\n"

     

    And here's the output at my end:

    HTTPS client sample started
    Provisioning certificate
    Waiting for network.. OK
    Connecting to vecka.nu
    Sent 58 bytes
    Received 367 bytes
    
    >        HTTP/1.1 200 OK
    
    Finished, closing socket.
    

     

    Note: you need mfw v1.2.3 or newer for SNI to work.

     

    Kind regards,

    Håkon

Related