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

RAUC Bundle Verification failing with Easy-RSA Framework #568

Closed
pclass-sensonix opened this issue Apr 6, 2020 · 20 comments
Closed

RAUC Bundle Verification failing with Easy-RSA Framework #568

pclass-sensonix opened this issue Apr 6, 2020 · 20 comments

Comments

@pclass-sensonix
Copy link

pclass-sensonix commented Apr 6, 2020

I've been successfully using RAUC in a new Embedded Linux product and am now at the point where I am setting up my own PKI. I am using Yocto to create my image.

In Yocto, I bbappend the rauc recipe with the following:

FILESEXTRAPATHS_prepend := "${THISDIR}/files:"
SRC_URI_append := " file://system.conf"
SRC_URI_append := " file://preinstall.sh"
SRC_URI_append := " file://postinstall.sh"
SRC_URI_append := " file://ca.cert.pem"

FILES_${PN} += " \
    /usr/lib/rauc/ \
"

do_install_append() {
    install -d ${D}/usr/lib/rauc/
    install -m 0755 ${WORKDIR}/preinstall.sh ${D}/usr/lib/rauc/
    install -m 0755 ${WORKDIR}/postinstall.sh ${D}/usr/lib/rauc/
}

Also, my bundle bitbake recipe declares the key and cert:

inherit bundle

RAUC_BUNDLE_COMPATIBLE ?= "X-image"

RAUC_BUNDLE_SLOTS ?= "rootfs"

RAUC_SLOT_rootfs ?= "X-image"

# Old
#RAUC_KEY_FILE = "${COREBASE}/meta-x/files/X-rauc-1.key.pem"
#RAUC_CERT_FILE = "${COREBASE}/meta-x/files/X-rauc-1.cert.pem"

# New
RAUC_KEY_FILE = "${TOPDIR}/conf/rauc-cert-and-key/X-rauc-1.key.pem"
RAUC_CERT_FILE = "${TOPDIR}/conf/rauc-cert-and-key/X-rauc-1.cert.pem"

Up until this point I was using the output of the openssl-ca.sh script from the Documentation mentioned here:
RAUC uses OpenSSL as a library for signing and verification of bundles. A PKI with intermediate CAs for the unit tests is generated by the test/openssl-ca.sh shell script available from GitHub, which may also be useful as an example for creating your own PKI.

Specifically, I put the ca.cert.pem file in /etc/rauc/ on the filesystem, and added the keychain directive to point to this file in the system.conf file - and everything worked great.

[keyring]
path=/etc/rauc/ca.cert.pem

Section 4.1.1. PKI Setup of the documentation ( https://readthedocs.org/projects/rauc/downloads/pdf/latest/ ) mentions "easy-rsa" as one method to setup your own PKI. That is what I used to setup my PKI on an Ubuntu 18.04 PC. I created a Root CA in easy-rsa with a public cert by the default name of ca.crt.

I also used the following command to generate a X.crt and X.key file pair to represent my Embedded Linux Device.

easyrsa build-client-full X nopass

I've tried to copy the X.crt file to the device under /etc/rauc as the name ca.cert.pem ( as well as ca.crt ) - however both files give the following error:

**rauc-Message: 00:02:57.886: Verifying bundle...
Apr 06 00:02:57 sama5d27-som1-ek-sd rauc[286]: (rauc:286): rauc-WARNING **: 00:02:57.914: signature verification failed: Verify error:unable to get local issuer certificate**

What do I have to do to get easy-rsa to work with RAUC?

Thanks!

@jluebbe
Copy link
Member

jluebbe commented Apr 6, 2020

"unable to get local issuer certificate" means that it doesn't find the (matching) ca or intermediate certificate.
You shouldn't put the signing certificate on the device as the keyring, but the root CA certificate.
If that doesn't work, could you post the full set of commands you used to configure easy-rsa?

@pclass-sensonix
Copy link
Author

pclass-sensonix commented Apr 6, 2020

Thanks @jluebbe for the comment. I double checked and I do have the root CA certificate as the keyring in system.conf and it is present by the name ca.cert.pem under /etc/rauc on the device.

Here are the steps I used to create the PKI with easy-rsa:

# Use Ubuntu 18.04 LTS as the basis for the Docker image.
FROM ubuntu:18.04

# Update / Install Packages
ENV DEBIAN_FRONTEND=noninteractive
...

# Create shared keys directory
RUN mkdir -p /pki-keys

# Clone Easy RSA
RUN cd / && mkdir -p source_and_env && cd source_and_env && git clone https://github.com/OpenVPN/easy-rsa.git && cd easy-rsa/easyrsa3/ && cp vars.example vars

# Configure the Easy RSA vars
WORKDIR /source_and_env/easy-rsa/easyrsa3/
RUN echo 'set_var EASYRSA_REQ_PROVINCE "x"' >> vars && \
    echo 'set_var EASYRSA_REQ_CITY "x"' >> vars && \
    echo 'set_var EASYRSA_REQ_ORG "x"' >> vars && \
    echo 'set_var EASYRSA_REQ_EMAIL "x"' >> vars && \
    echo 'set_var EASYRSA_REQ_OU "x"' >> vars && \
    echo 'set_var EASYRSA_KEY_SIZE "x"' >> vars && \
    echo 'set_var EASYRSA_CA_EXPIRE "x"' >> vars && \
    echo 'set_var EASYRSA_CERT_EXPIRE "x"' >> vars && \
    echo 'set_var EASYRSA_SSL_CONF "$EASYRSA/openssl-easyrsa.cnf"' >> vars && \
    echo 'set_var EASYRSA_REQ_CN "x"' >> vars && \
    echo 'set_var EASYRSA_DN "org"' >> vars

# Configure the OpenSSL Config
RUN echo [ code_sign ] >> openssl-easyrsa.cnf && \
    echo basicConstraints=CA:FALSE >> openssl-easyrsa.cnf && \
    echo keyUsage = digitalSignature >> openssl-easyrsa.cnf && \
    echo extendedKeyUsage = codeSigning >> openssl-easyrsa.cnf && \
    echo subjectKeyIdentifier=hash >> openssl-easyrsa.cnf && \
    echo authorityKeyIdentifier=keyid,issuer >> openssl-easyrsa.cnf

# Setup the environment
ENV EASYRSA /source_and_env/easy-rsa/easyrsa3
ENV PATH $EASYRSA:$PATH
ENV EASYRSA_PKI /pki

# Initialize the PKI
RUN easyrsa init-pki

# Copy the SSL Config Files
RUN cp /source_and_env/easy-rsa/easyrsa3/openssl-easyrsa.cnf /pki/openssl-easyrsa.cnf ; cp /source_and_env/easy-rsa/easyrsa3/openssl-easyrsa.cnf /pki/safessl-easyrsa.cnf

# Build a Root CA
RUN (printf "\n\n\n\n\n\n\n" && cat) | easyrsa build-ca nopass

# Generate the DH ( DilHellman )
#RUN easyrsa gen-dh

# Generate a server certificate request and key
RUN (printf "\n\n\n\n\n\n\n" && cat) | easyrsa gen-req X-PKI-Server nopass

# Sign the certificate .crt file needed by the server
RUN (printf "yes" && cat) | easyrsa sign-req server X-PKI-Server nopass

# Verify Server Cert
WORKDIR /pki
RUN openssl verify -CAfile ca.crt issued/X-PKI-Server.crt

# Run bash
CMD /bin/bash

@pclass-sensonix
Copy link
Author

pclass-sensonix commented Apr 6, 2020

@jluebbe One more bit of information, to be clear - this is what I have /etc/rauc on the device:

/etc/rauc# ls -lrt
total 13
-rw-r--r-- 1 root root  327 Apr  6 13:10 system.conf
-rw-r--r-- 1 root root 2488 Apr  6 13:10 ca.cert.pem
-rwxr-xr-x 1 root root 8300 Apr  6 13:10 X-PKI-Server.crt

The "ca.cert.pem" above, is the same as the easy-rsa /pki/ca.crt file.

The system.conf file has the following entry:

[keyring]
path=/etc/rauc/X-PKI-Server.crt

And the error is:

Apr 06 13:40:19 my-machine rauc[273]: rauc-Message: 13:40:19.766: Reading bundle: /fw/fw_update.raucb
Apr 06 13:40:19 my-machine rauc[273]: rauc-Message: 13:40:19.845: Verifying bundle...
Apr 06 13:40:19 my-machinerauc[273]: (rauc:273): rauc-WARNING **: 13:40:19.912: signature verification failed: Verify err
or:unable to get local issuer certificate
Apr 06 13:40:19 my-machine rauc[273]: rauc-Message: 13:40:19.914: installing /fw/fw_update.raucb: signature verification f
ailed: Verify error:unable to get local issuer certificate
Apr 06 13:40:19 my-machine rauc[273]: rauc-Message: 13:40:19.920: installing /fw/fw_update.raucb: finished
Apr 06 13:40:19 my-machine rauc[273]: rauc-Message: 13:40:19.923: installing `/fw/fw_update.raucb` failed: 1

Thank you.

@jluebbe
Copy link
Member

jluebbe commented Apr 6, 2020

extendedKeyUsage = codeSigning is currently not supported (but I'm working on it at the moment). Could you try without any key usage?

@pclass-sensonix
Copy link
Author

@jluebbe I just rebuilt my Yocto image with a new set of keys generated from Easy-RSA. I took out the codeSigning section but unfortunately, it still fails.

The error indicates a suitable CA Cert cannot be found to verify the bundle.

Does RAUC only look at the cert file specificed in system.conf ( meaning it does not have to be known to ca-certificates )?
Also, does RAUC have a way of verifying the bundle locally from the comand line ( this way I can try verifying without doing an "Install" on DBUS)?

Thank you very much for the help.

@ejoerns
Copy link
Member

ejoerns commented Apr 6, 2020

@pclass-sensonix you can specify both path= and directory= for looking up keyrings. If you specify path= only, no other keyring file will be checked.

You can verify files locally with rauc info --keyring=/path/to/keyring <path-to-bundle>.

@pclass-sensonix
Copy link
Author

@ejoerns Thanks for the information - that is good to know.

It seems neither the ca.cert.pem or X-PKI-Server.crt generated from easy-rsa work - please see the following:

root@my-machine:/fw# ls -rlt /etc/rauc/
total 13
-rw-r--r-- 1 root root  327 Apr  6 16:50 system.conf
-rw-r--r-- 1 root root 2488 Apr  6 16:50 ca.cert.pem
-rwxr-xr-x 1 root root 8300 Apr  6 16:50 X-PKI-Server.crt

root@my-machine:/fw# ls -lrt
total 72956
drwx------ 2 root root    16384 Apr  6 16:55 lost+found
-rw-r--r-- 1 root root 74689334 Apr  6 17:53 fw_update.raucb

root@my-machine:/fw# rauc info --keyring=/etc/rauc/ca.cert.pem fw_update.raucb 
rauc-Message: 17:58:10.270: Reading bundle: /fw/fw_update.raucb
rauc-Message: 17:58:10.308: Verifying bundle... 
signature verification failed: Verify error:unable to get local issuer certificate

root@my-machine:/fw# rauc info --keyring=/etc/rauc/X-PKI-Server.crt  fw_update.raucb 
rauc-Message: 17:58:25.927: Reading bundle: /fw/fw_update.raucb
rauc-Message: 17:58:26.010: Verifying bundle... 
signature verification failed: Verify error:unable to get local issuer certificate

@jluebbe
Copy link
Member

jluebbe commented Apr 6, 2020

I've pushed my branch to support the code-signing purpose: https://github.com/jluebbe/rauc/commits/cert-purpose

If that doesn't help here, I'll have to reproduce the setup you're using. Could you send the output of openssl x509 -text < [foo.cert.pem] for your root and leaf certificates?

@pclass-sensonix
Copy link
Author

Thanks @jluebbe. I will try the new branch now.

In the meantime, I've attached the text dumps of the root and leaf certificates here.

Leaf.txt
Root.txt

@pclass-sensonix
Copy link
Author

@jluebbe - An update. I built and tried your latest branch:


root@my-machine:/etc/rauc# rauc --version
rauc 1.2.129-0ab9

Unfortunately, I get the same issue.

@jluebbe
Copy link
Member

jluebbe commented Apr 7, 2020

This leaf cert is not signed by this root cert. You can check that by comparing the information in the leaf's authority key id

X509v3 Authority Key Identifier:
    keyid:83:E8:C1:84:4E:8F:06:B0:69:6B:F6:69:50:88:C0:A4:9A:0B:1B:03
    DirName:/C=US/ST=Minnesota/L=x/O=x/OU=x/CN=Easy-RSA CA/emailAddress=x@x.com
    serial:38:B0:B7:90:89:41:8A:53:D7:D9:AB:B3:79:DC:B3:FD:93:CE:EF:6C

with the root's subject key id

X509v3 Subject Key Identifier:
    D6:17:CD:1C:D2:08:46:A8:20:CE:E3:20:F2:06:FA:3B:12:2C:02:E5

You can see that the root cert is self-signed (the authority key id is it's own).

X509v3 Authority Key Identifier:
    keyid:D6:17:CD:1C:D2:08:46:A8:20:CE:E3:20:F2:06:FA:3B:12:2C:02:E5
    DirName:/C=US/ST=x/L=x/O=x/OU=x/CN=Easy-RSA CA/emailAddress=x@x.com
    serial:1C:B3:16:51:79:86:3B:C7:F9:3C:43:26:20:C8:59:90:5A:54:D2:C9

@pclass-sensonix
Copy link
Author

@jluebbe Thanks for the information! I am getting closer. Now I get the error:

rauc-Message: 19:18:00.280: Reading bundle: /fw/fw_update.raucb
rauc-Message: 19:18:00.492: Verifying bundle... 
signature verification failed: Verify error:unsupported certificate purpose

I was using the wrong command for easy-rsa - apparently I needed to do:

easyrsa build-serverClient-full myclient nopass

instead of:

easyrsa build-client-full myclient nopass

root@my-machine:/tmp$ grep -C 3 "Authority Key Id" ca.crt 
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                83:E8:C1:84:4E:8F:06:B0:69:6B:F6:69:50:88:C0:A4:9A:0B:1B:03
            X509v3 Authority Key Identifier: 
                keyid:83:E8:C1:84:4E:8F:06:B0:69:6B:F6:69:50:88:C0:A4:9A:0B:1B:03
                DirName:/C=US/ST=Minnesota/L=x/O=x/OU=x/CN=Easy-RSA CA/emailAddress=x@x.com
                serial:38:B0:B7:90:89:41:8A:53:D7:D9:AB:B3:79:DC:B3:FD:93:CE:EF:6C
root@my-machine:/tmp$ grep -C 3 "Subject Key Id" ca.crt 
                    3b:95:a9
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier: 
                83:E8:C1:84:4E:8F:06:B0:69:6B:F6:69:50:88:C0:A4:9A:0B:1B:03
            X509v3 Authority Key Identifier: 
                keyid:83:E8:C1:84:4E:8F:06:B0:69:6B:F6:69:50:88:C0:A4:9A:0B:1B:03
root@my-machine:/tmp$ grep -C 3 "Authority Key Id" sx.cert 
                CA:FALSE
            X509v3 Subject Key Identifier: 
                31:58:B6:21:68:CB:C1:5D:69:66:12:23:07:29:5E:5C:EA:61:BE:0D
            X509v3 Authority Key Identifier: 
                keyid:83:E8:C1:84:4E:8F:06:B0:69:6B:F6:69:50:88:C0:A4:9A:0B:1B:03
                DirName:/C=US/ST=Minnesota/L=x/O=x/OU=x/CN=Easy-RSA CA/emailAddress=x@x.com
                serial:38:B0:B7:90:89:41:8A:53:D7:D9:AB:B3:79:DC:B3:FD:93:CE:EF:6C


openssl verify -CAfile ca.crt my-rauc-1.cert.pem 
my-rauc-1.cert.pem: OK

@jluebbe
Copy link
Member

jluebbe commented Apr 8, 2020

If your certificates still have "TLS Web Server Authentication" you need to specify the corresponding purpose for verification. You need to use #570 to have the necessary support for that.

Alternatively, if this CA will only be used to sign rauc bundles, you could configure easy-rsa to no add key usage attributes to the certificates.

@pclass-sensonix
Copy link
Author

@jluebbe Thank you for the help with this issue. I will wait for that pull-request to be merged. I need to use this CA for other purposes as well.

@jluebbe
Copy link
Member

jluebbe commented Apr 9, 2020

The PR now contains some more documentation and I'd very much appreciate some external testing.

@pclass-sensonix
Copy link
Author

@jluebbe The following works for me with my own Easy-RSA PKI ( ca.crt ):

[keyring]
path=/etc/rauc/ca.crt
check-purpose=any

Thanks for your work on this!
Will this pull request be merged in the near future?

@jluebbe
Copy link
Member

jluebbe commented Apr 20, 2020

If only check-purpose=any works for you, it seems that you have incompatible keyUsage/extendedKeyUsage attributes in your certificate chain (which is probably not what you want to deploy in a product). The PR still needs in-depth review, as it touches the signature code.

@jluebbe
Copy link
Member

jluebbe commented Apr 29, 2020

The check-purpose feature has been released with 1.3.

Nevertheless: check-purpose=any should only be regarded as a debugging aid. I still think that there is something inconsistent in your certificates.

@pclass-sensonix
Copy link
Author

@jluebbe I agree there must be something inconsistent there - I still need to investigate. I did verify that this worked in our Yocto builds. Thanks for the work on this issue.

@Psykar
Copy link
Contributor

Psykar commented Feb 1, 2021

At risk of a slight necro (because I'm currently stuck on 1.2 which doesn't support check-purpose) it's also possible to tell easy-rsa to not set keyUsage / extendedKeyUsage by creating a new file in x509-types with those lines removed. (you can also drop it in the pki/x509-types folder)

eg. copy code-signing to rauc containing something like

# X509 extensions for a client

basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always

Then sign the key mentioning that type.
easyrsa sign-req rauc <filename_base>

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

No branches or pull requests

4 participants