Hi Kackle123,
Thanks for the report. I've pushed a fix in PR #39 here:
https://github.com/wolfSSL/wolfMQTT/pull/39
David Garske, wolfSSL
You are not logged in. Please login or register.
Please post questions or comments you have about wolfSSL products here. It is helpful to be as descriptive as possible when asking your questions.
ReferenceswolfSSL - Embedded SSL Library → Posts by dgarske
Hi Kackle123,
Thanks for the report. I've pushed a fix in PR #39 here:
https://github.com/wolfSSL/wolfMQTT/pull/39
David Garske, wolfSSL
Hi Eyal,
That's wonderful! Very happy you got it all working.
Let me know if you have any other questions or issues.
Cheers,
David Garske
Hi Eyal,
What you have is an incomplete CSR, which is missing the signature. When comparing the one you generated with one from openssl the only difference was the missing signature at the bottom:
openssl asn1parse -inform der -in mycsr.der -dump
...
248:d=1 hl=2 l= 9 cons: SEQUENCE
250:d=2 hl=2 l= 7 prim: OBJECT :ecdsa-with-SHA1
259:d=1 hl=2 l= 72 prim: BIT STRING
Here is a complete code example for creating a valid CSR.
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/asn_public.h>
#define MAX_TEMP_SIZE 1024
/* Build using:
gcc -lwolfssl -o makecsr makecsr.c
*/
int main(void)
{
ecc_key key;
WC_RNG rng;
Cert req;
byte der[MAX_TEMP_SIZE], pem[MAX_TEMP_SIZE];
int derSz, pemSz;
wc_ecc_init(&key);
wc_InitRng(&rng);
wc_ecc_make_key_ex(&rng, 32, &key, ECC_SECP256R1);
derSz = wc_EccKeyToDer(&key, der, sizeof(der));
memset(pem, 0, sizeof(pem));
pemSz = wc_DerToPem(der, derSz, pem, sizeof(pem), ECC_PRIVATEKEY_TYPE);
printf("%s", pem);
wc_InitCert(&req);
strncpy(req.subject.country, "US", CTC_NAME_SIZE);
strncpy(req.subject.state, "OR", CTC_NAME_SIZE);
strncpy(req.subject.locality, "Portland", CTC_NAME_SIZE);
strncpy(req.subject.org, "yaSSL", CTC_NAME_SIZE);
strncpy(req.subject.unit, "Development", CTC_NAME_SIZE);
strncpy(req.subject.commonName, "www.wolfssl.com", CTC_NAME_SIZE);
strncpy(req.subject.email, "info@wolfssl.com", CTC_NAME_SIZE);
derSz = wc_MakeCertReq(&req, der, sizeof(der), NULL, &key);
req.sigType = CTC_SHA256wECDSA;
derSz = wc_SignCert(req.bodySz, req.sigType, der, sizeof(der), NULL, &key, &rng);
pemSz = wc_DerToPem(der, derSz, pem, sizeof(pem), CERTREQ_TYPE);
printf("%s", pem);
wc_ecc_free(&key);
wc_FreeRng(&rng);
return 0;
}
gcc -lwolfssl -o makecsr makecsr.c
./makecsr > mycsr.csr
cat mycsr.csr
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIJEIx4rTDoZFi7lsCiOX7XyTXnXOvj4VPDoQDGeD4p8woAoGCCqGSM49
AwEHoUQDQgAEMZygsN1xZH/QRxMszDej8bL84by+XQ4sziXUT83HGkTUx9puoNeI
UxlctiaTT1IgwCg9GCpC52SXU/e/NtvoUw==
-----END EC PRIVATE KEY-----
-----BEGIN CERTIFICATE REQUEST-----
MIIBSTCB8QIBAjCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk9SMREwDwYDVQQH
DAhQb3J0bGFuZDEOMAwGA1UECgwFeWFTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50
MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9A
d29sZnNzbC5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQxnKCw3XFkf9BH
EyzMN6PxsvzhvL5dDizOJdRPzccaRNTH2m6g14hTGVy2JpNPUiDAKD0YKkLnZJdT
97822+hToAAwCgYIKoZIzj0EAwIDRwAwRAIgMdviSP9zLvYaNm1hcCVqG8jOvJz2
T34DlP3XXKI3cZ4CIFsNEquqCPbIkKGC8pOW9fUcmf6sWlgrra6uedL+PaCF
-----END CERTIFICATE REQUEST-----
openssl req -in mycsr.csr -text -noout
Certificate Request:
Data:
Version: 2 (0x2)
Subject: C=US, ST=OR, L=Portland, O=yaSSL, OU=Development, CN=www.wolfssl.com/emailAddress=info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
EC Public Key:
pub:
04:31:9c:a0:b0:dd:71:64:7f:d0:47:13:2c:cc:37:
a3:f1:b2:fc:e1:bc:be:5d:0e:2c:ce:25:d4:4f:cd:
c7:1a:44:d4:c7:da:6e:a0:d7:88:53:19:5c:b6:26:
93:4f:52:20:c0:28:3d:18:2a:42:e7:64:97:53:f7:
bf:36:db:e8:53
ASN1 OID: prime256v1
Attributes:
a0:00
Signature Algorithm: ecdsa-with-SHA256
30:44:02:20:31:db:e2:48:ff:73:2e:f6:1a:36:6d:61:70:25:
6a:1b:c8:ce:bc:9c:f6:4f:7e:03:94:fd:d7:5c:a2:37:71:9e:
02:20:5b:0d:12:ab:aa:08:f6:c8:90:a1:82:f2:93:96:f5:f5:
1c:99:fe:ac:5a:58:2b:ad:ae:ae:79:d2:fe:3d:a0:85
Let me know if you have any questions.
Thanks,
David Garske, wolfSSL
Hi Eyal,
I'm happy to hear you got it working!
The `-----BEGIN EC PARAMETERS-----\nBggqhkjOPQMBBw==\n-----END EC PARAMETERS-----` part is static. Meaning for a prime256v1 256-bit key its always the same and you can always pre-pend it to the generated key if its required. This is just a base 64 encoded ASN1 object id, which indicates prime256v1. I've added this to our feature request list. It would be good for us to have the ability to generate these ECC parameters.
The default curve type is the NIST prime curves, so when calling wc_ecc_make_key with 32 you get a NIST prime256v1 curve. If you use the wc_ecc_make_key_ex function you can provide a curve_id such as `ECC_SECP256R1`.
You can see all the ECC build options here:
https://github.com/wolfSSL/wolfssl/blob … /ecc.c#L32
You can see a list of all supported curves here:
https://github.com/wolfSSL/wolfssl/blob … ecc.c#L456
If you would like to save code space you can define `ECC_USER_CURVES`, which allows you to define specific curve sizes manually using the 'HAVE_ECC###`defines (256-bit is on by default).
Thanks,
David Garske, wolfSSL
Hi Eyal,
If you are only using the wolfCrypt portion of the library you can:
1. define `WOLFCRYPT_ONLY`.
2. Include relevant source files in /wolfcrypt/src/*.c
3. Include relevant headers in /wolfssl/wolfcrypt/*.h
For the build options you are using the only files you would to include are: asn.c, ecc.c, sha256.c and random.c. However I would recommend pulling in all the files/headers and letting the linker optimize out any used functions. This should the same code size, but allow you to expand your use.
If you do not have a hardware RNG, then you should use the pseudo DBRG based on SHA256. To seed the DRBG you'll need to find some random source such as a microsecond counter or ADC noise.
Here are the defines and code example for doing this:
#define HAVE_HASHDRBG
#define CUSTOM_RAND_TYPE unsigned int
extern unsigned int custom_rand_generate(void);
#define CUSTOM_RAND_GENERATE custom_rand_generate
unsigned int custom_rand_generate(void)
{
/* TODO: build 32-bits of RNG and return */
return myRng;
}
Thanks,
David Garske, wolfSSL
Hi Eyal,
Thanks for evaluating wolfSSL! We have many customers using the STM32F4 with FreeRTOS. That is a great question!
To generate an ECC key:
1. Make sure you have the `HAVE_ECC` defined.
2. Call:
ecc_key eccKey;
wc_ecc_make_key(rng, keySize, & eccKey);
Example: https://github.com/wolfSSL/wolfssl/blob … t.c#L11231
To create a CSR based on this ECC key:
1. Make sure you have `WOLFSSL_CERT_GEN` and `WOLFSSL_CERT_REQ` defined.
2. Call:
Cert req;
wc_MakeCertReq(&req, der, derSz, NULL, &eccKey);
Example: https://github.com/wolfSSL/wolfssl/blob … st.c#L8953
For an embedded system I find it best to put all my build options into a `user_settings.h` file (somewhere in your include path) and define `WOLFSSL_USER_SETTINGS`. You can find a good example for this here:
https://github.com/wolfSSL/wolfssl/blob … settings.h
Let me know if you have any issues or further questions.
Thanks,
David Garske, wolfSSL
Hi tdoering,
Thanks for the excellent question and details.
Yes having an intermediate CA for each device, which generated and signed by a root during manufacturing is a very good solution.
The server certificate for the TLS server should present a cert chain with the server peer certificate first, then the intermediate cert. If the public root CA is loaded on the key store/browser then this will be a valid certificate chain.
We have an example for creating a server certificate at runtime here:
https://github.com/wolfSSL/wolfssl-examples/pull/70
You can find examples for creating a cert request and having it signed here:
https://github.com/wolfSSL/wolfssl/blob … st.c#L8900
Let me know if you have any issues or questions.
Thanks,
David Garske, wolfSSL
Hi Brad,
I would agree with it being a stack size issue, but if you've increased it to 132KB that would be more than required. Depending on the configuration a typical stack use for a TLS session is about 15 KB.
Its possible there is a BIG ENDIAN issue, but we continuously test with little and big endian, so I don't think that's the problem.
There are a couple of defines you can try using that might help:
#define ECC_TIMING_RESISTANT
#define NO_64BIT
The NO_64BIT could help if your compiler is having issue with the long long type. The ECC timing resistance uses a different math computation that is slower, but uses less stack.
Also you can limit the ECC curve size for by using `#define ECC_USER_CURVES`. This will enable only 256-bit curves by default and you can use defines like `HAVE_ECC384` to enable other curve sizes.
Here is an ECC section of a `user_settings.h`, which might be helpful:
https://github.com/wolfSSL/wolfssl/blob … ings.h#L48
Let me know if this helps or if you have any other questions.
Thanks,
David Garske, wolfSSL
Hi Nimesh,
To include wolfMQTT into your project you can either include the sources directly or compile them as a static library. I would recommend doing it the same as you are doing with wolfSSL. Either way is supported.
The wolfMQTT library itself is very compact (only about 4 KB). The only RAM allocated is for the TX/RX buffer, which defaults to 1024 bytes, but can be reduced.
I don't have any documentation for using wolfMQTT with TI_RTOS, but if you've got it working with wolfSSL then it should be easy to add wolfMQTT. The wolfMQTT library has no RTOS dependencies besides the network callbacks in examples/mqttnet.c. You can use that file as a template for implementing the TI_RTOS network calls.
The best reference for TI_RTOS can be found here:
https://github.com/wolfSSL/wolfssl/tree/master/tirtos
Thanks,
David Garske, wolfSSL
Hi Nimesh,
It sounds like you've already got past the most difficult part which is getting TLS running. Adding wolfMQTT on top is quite simple. You can download the latest source code for wolfMQTT v0.13 here:
https://github.com/wolfSSL/wolfMQTT
We have an example for using AWS in the 'examples/aws/awsiot.c` file. To enable TLS support build with the define `ENABLE_MQTT_TLS` set. You may need to change the `examples/mqttnet.c` to use TI-RTOS compatible network calls.
Let me know if you have any issues or questions.
Thanks,
David Garske, wolfSSL
Hi Gussabina,
The IO read callback will ask for X bytes. If your network return X+10 bytes (for example) you will need to cache the extra 10 bytes until the next callback. Typically when you ask a network stack for X bytes it only returns X bytes. However if you are using something besides a network stack and asking the hardware for a buffer, you may receive more than X bytes. Its up to you to cache those extra bytes until the next IO read callback.
Let me know if that helps or not.
Thanks,
David Garske, wolfSSL
Hi Gussabina,
That explains the issue you are seeing. The protection needs to happen at the MQTT protocol level since MQTT does not provide a way to split up publish messages. There is a header and the message follows behind which may span over multiple TLS / TCP packets. Additionally the publish being sent can respond with a confirmation if using Qos of 1 or 2.
So the answer is you will need to implement a way to make sure each thread has exclusive access to the MQTT library. I'd recommend either have single thread and using FreeRTOS queue to pass between threads or adding mutex protection around both MQTT tasks and implement non-blocking MQTT mode so it does not block and each thread gets access to the socket.
Thanks,
David Garske, wolfSSL
Hi Gussabina,
If you are using FreeRTOS you can define `FREERTOS` instead of `SINGLE_THREADED` to enable mutex protection in the wolfSSL library.
The wolfMQTT library on the other-hand does not support multi-threads. To solve that you have a couple options:
1. Have one thread dedicated to handling the RX and TX of publish messages. Define `WOLFMQTT_NONBLOCK` and if you get back the `MQTT_CODE_CONTINUE` response code then it means no RX data is available. You can then use/check a FreeRTOS queue for any messages to TX.
2. Use a mutex to protect access to the socket between two threads. You'll also need to use non-blocking mode so you aren't blocked on the socket read.
It sounds like the eventual failure might be due to multiple threads trying to rx/tx publish messages at the same time. This would get the data in the socket out of sync and probably cause the decrypt error.
Thanks,
David Garske, wolfSSL
Hi Gus,
Typically if things break-down after the connection has already been running fine indicates to me some memory issue either with corruption or memory leak. I recommend adding some memory checking to measure heap use and also stack use. We have some hooks for monitoring heap that can be enabled using `WOLFSSL_TRACK_MEMORY`. This will add tracking on XMALLOC/XFREE and display a result on wolfSSL_Cleanup() or `ShowMemoryTracker()`. Measuring stack is typically RTOS specific. What OS / Micro-controller are you using? Are you using any hardware crypto acceleration?
A typical recovery for a connection error would be to call `wolfSSL_shutdown(ssl)`, `wolfSSL_free(ssl)` and `close()` the socket. This will cleanup everything and allow you to reconnect again just as you did before. If you are having a memory issue I suspect you'll see problems reconnecting as well. We have a collection of TLS examples here: https://github.com/wolfSSL/wolfssl-exam … master/tls
Thanks,
David Garske, wolfSSL
Hi Csaba,
The wolfCrypt test results up to the point of failure look normal. Typically when we see a failure in RSA its because of a memory or configuration issue.
Please check the following:
1. Make sure your stack enough reserved space. For my wolfCrypt test on a PIC32MZ here I set it to 20480 bytes.
2. If you are setting the FP_MAX_BITS make sure and use the max key size times 2 (so 2048-bit RSA will require `#define FP_MAX_BITS 4096`).
3. For the wolfCrypt self test it requires certificates. Typically these come from the file system in ./certs. If NO_FILESYSTEM is defined then you'll need to set either USE_CERT_BUFFERS_2048 or USE_CERT_BUFFERS_1024 depending on your FP_MAX_BITS.
For setting up the library to just enable SHA1 and RSA you can define `WOLFSSL_USER_SETTINGS` and the `user_settings.h`file somewhere in your include path. You can find examples for this here:
https://github.com/wolfSSL/wolfssl/blob … settings.h
If this doesn't help please let me know the error code from the failed wc_Rsa function and the test which is failing.
Thanks,
David Garske, wolfSSL
Hi Kackle123,
That's excellent you got it working! Thanks for sending that information. I'll look into the use of `htons` for MQX in the wolfMQTT examples and see if I can fix that.
Thanks,
David Garske, wolfSSL
Hi kackle123,
Your description of the issue sounds like an MQX networking problem. Perhaps take a step back and setup a simple TCP socket client example to validate your networking functionality would be good.
The wolfSSL library does not handle socket connect or disconnect. With a typical TLS implementation the socket is created and host connected, then `wolfSSL_set_fd()` is called so the wolf IO layer knows the socket descriptor handle to read()/write(). The wolfMQTT library uses the `WOLFSSL_USER_IO` define to enable setting IO callbacks using wolfSSL_SetIORecv() and wolfSSL_SetIOSend(), which handle the read/write inside the wolfMQTT application.
See this code sections for details:
https://github.com/wolfSSL/wolfMQTT/blo … ket.c#L302
The `MqttSocket_Connect()` function first opens the socket using the defined net->connect callback function, then sets up the WOLFSSL object and calls `wolfSSL_connect()`.
If you can send over any logs, code changes or wireshark trace, those will help in understanding the problem.
Thanks,
David Garske, wolfSSL
Hi mariocaptain,
Thank you for your interest in our wolfMQTT/wolfSSL solution.
You can find our Arduino examples for wolfMQTT and wolfSSL here:
https://github.com/wolfSSL/wolfMQTT/tre … DE/ARDUINO
https://github.com/wolfSSL/wolfssl/tree … DE/ARDUINO
Our AWS IoT Hub MQTT example is here:
https://github.com/wolfssl/wolfmqtt#aws-iot-example
https://github.com/wolfSSL/wolfMQTT/blo … s/awsiot.c
To utilize a non-BSD socket network interface we have a template for using a different transport here:
https://github.com/wolfSSL/wolfMQTT/blo … mqttuart.c
Let me know if you have any other questions or issues.
Thanks,
David Garske, wolfSSL
Hi Kackle123,
If your AWS log shows access denied, then your socket connect() has already occurred and you've entered into the TLS handshake. AWS uses TLS mutual authentication, which requires the device (client) also present a certificate for authentication. Those client certificates are generated by AWS or you can load your own CA and sign them yourself.
See our example here:
https://github.com/wolfSSL/wolfMQTT/blo … iot.c#L193
http://docs.aws.amazon.com/iot/latest/d … ntity.html
To better support this it would be helpful to turn on wolfSSL debugging logs and capture a wireshark trace and send that over. You can email support@wolfssl.com and reference this forum case if you want to keep it confidential.
For logs you need to define `DEBUG_WOLFSSL` and call `wolfSSL_Debugging_ON();` prior to `wolfSSL_Init();`.
Thanks,
David Garske, wolfSSL
Hi Sanjay,
The call to set cipher list is failing, but you are not checking the return code. The correct syntax for the cipher suite is: `ECDHE-RSA-AES128-GCM-SHA256`. You can use this command to see a list of supported cipher suites: `./examples/client/client -e`.
`./examples/client/client -h 66.83.75.170 -p 443 -c ./certtest/Demo_Cert.pem -A ./certtest/CA_Root.pem -d -l ECDHE-RSA-AES128-GCM-SHA256`
Also we have some simple TLS client examples here:
https://github.com/wolfSSL/wolfssl-exam … master/tls
Let me know if that resolves the issue.
Thanks,
David Garske, wolfSSL
Hi Kackle123,
For TLS the socket must be open first then the call to wolfSSL_connect(). If you are having trouble getting past the socket `connect()` that indicates a network level problem. Have you verified you can reach the host? Can you provide some additional information on the platform you are using and how you are building it?
If you are building wolfMQTT for AWS you'll need to make sure TLS support is enabled either using `./configure --enable-tls` or `#define ENABLE_MQTT_TLS`.
Thanks,
David Garske, wolfSSL
Hi Nimesh,
I see you are using the tirtos package build. You'll need to add `gnuOpts += "-DUSE_WOLF_STRTOK";` to `tirtos/wolfssl.bld`.
Let me know if that helps.
Thanks, David G.
Hi Nimesh,
We recently implemented a custom strtok replacement to resolve build environments that do not have an implementation. We found MINGW and a few other build environments are missing this, so we wrote our own.
This change was merged into master on Aug 17, 2017. You can find the pull request here:
https://github.com/wolfSSL/wolfssl/pull/1105
To force use of this define `USE_WOLF_STRTOK`. With configure this would be `./configure CFLAGS="-D USE_WOLF_STRTOK"`.
Let me know if this helps.
Thanks,
David Garske, wolfSSL
Hi Andrey,
I pushed a few changes to a branch for you to try. I am working on integrating this with another PR to add STM32 CubeMX hashing support. That should be pushed later today.
For now you can find the commit with this fix here:
https://github.com/dgarske/wolfssl/comm … 57d1b36491
The patch is attached. Let me know your results.
Thanks,
David Garske, wolfSSL
Hi Andrey,
My name is David Garske and I'm one of the wolfSSL engineers. I'm working on resolving this issue now. I agree the STM32F2 doesn't support hardware accelerated AES GCM. I'll post an updated with a pull request link shortly.
Thanks,
David Garske, wolfSSL
wolfSSL - Embedded SSL Library → Posts by dgarske
Powered by PunBB, supported by Informer Technologies, Inc.
Generated in 0.023 seconds (71% PHP - 29% DB) with 5 queries