diff options
-rw-r--r-- | fastbootd/Android.mk | 4 | ||||
-rw-r--r-- | fastbootd/commands.c | 39 | ||||
-rw-r--r-- | fastbootd/commands/flash.c | 47 | ||||
-rw-r--r-- | fastbootd/commands/flash.h | 2 | ||||
-rw-r--r-- | fastbootd/fastbootd.c | 2 | ||||
-rw-r--r-- | fastbootd/other/sign/src/SignImg.java | 181 | ||||
-rw-r--r-- | fastbootd/secure.c | 166 | ||||
-rw-r--r-- | fastbootd/secure.h | 53 | ||||
-rw-r--r-- | fastbootd/utils.c | 13 | ||||
-rw-r--r-- | fastbootd/utils.h | 1 |
10 files changed, 8 insertions, 500 deletions
diff --git a/fastbootd/Android.mk b/fastbootd/Android.mk index 0f1facb..f7c67a9 100644 --- a/fastbootd/Android.mk +++ b/fastbootd/Android.mk @@ -30,7 +30,6 @@ LOCAL_SRC_FILES := \ commands/virtual_partitions.c \ fastbootd.c \ protocol.c \ - secure.c \ transport.c \ trigger.c \ usb_linux_client.c \ @@ -38,12 +37,11 @@ LOCAL_SRC_FILES := \ LOCAL_MODULE := fastbootd LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter -DFLASH_CERT +LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter LOCAL_LDFLAGS := -ldl LOCAL_SHARED_LIBRARIES := \ libhardware \ - libcrypto \ libhardware_legacy LOCAL_STATIC_LIBRARIES := \ diff --git a/fastbootd/commands.c b/fastbootd/commands.c index 2f6e86a..83e86b0 100644 --- a/fastbootd/commands.c +++ b/fastbootd/commands.c @@ -52,8 +52,6 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg) { - int sz, atags_sz, new_atags_sz; - int rv; unsigned kernel_actual; unsigned ramdisk_actual; unsigned second_actual; @@ -61,11 +59,9 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg) void *ramdisk_ptr; void *second_ptr; struct boot_img_hdr *hdr; - char *ptr = NULL; - char *atags_ptr = NULL; - char *new_atags = NULL; - int data_fd = 0; - + int sz, atags_sz, new_atags_sz; + int rv; + char *ptr = NULL, *atags_ptr = NULL, *new_atags = NULL; D(DEBUG, "cmd_boot %s\n", arg); if (phandle->download_fd < 0) { @@ -79,18 +75,9 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg) goto error; } - // TODO: With cms we can also verify partition name included as - // cms signed attribute - if (flash_validate_certificate(phandle->download_fd, &data_fd) != 1) { - fastboot_fail(phandle, "Access forbiden you need the certificate"); - return; - } - - sz = get_file_size(data_fd); - + sz = get_file_size(phandle->download_fd); ptr = (char *) mmap(NULL, sz, PROT_READ, - MAP_POPULATE | MAP_PRIVATE, data_fd, 0); - + MAP_POPULATE | MAP_PRIVATE, phandle->download_fd, 0); hdr = (struct boot_img_hdr *) ptr; if (ptr == MAP_FAILED) { @@ -143,7 +130,6 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg) free(atags_ptr); munmap(ptr, sz); free(new_atags); - close(data_fd); D(INFO, "Kexec going to reboot"); reboot(LINUX_REBOOT_CMD_KEXEC); @@ -270,7 +256,6 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg) char data[BOOT_MAGIC_SIZE]; char path[PATH_MAX]; ssize_t header_sz = 0; - int data_fd = 0; D(DEBUG, "cmd_flash %s\n", arg); @@ -288,14 +273,9 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg) return; } - if (flash_validate_certificate(phandle->download_fd, &data_fd) != 1) { - fastboot_fail(phandle, "Access forbiden you need certificate"); - return; - } - // TODO: Maybe its goot idea to check whether the partition is just bootable partition if (!strcmp(arg, "boot") || !strcmp(arg, "recovery")) { - if (read_data_once(data_fd, data, BOOT_MAGIC_SIZE) < BOOT_MAGIC_SIZE) { + if (read_data_once(phandle->download_fd, data, BOOT_MAGIC_SIZE) < BOOT_MAGIC_SIZE) { fastboot_fail(phandle, "incoming data read error, cannot read boot header"); return; } @@ -307,10 +287,7 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg) partition = flash_get_partiton(path); - sz = get_file_size64(data_fd); - - sz -= header_sz; - + sz = get_file_size64(phandle->download_fd); if (sz > get_file_size64(partition)) { flash_close(partition); D(WARN, "size of file too large"); @@ -327,8 +304,6 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg) D(INFO, "partition '%s' updated\n", arg); flash_close(partition); - close(data_fd); - //TODO: check who is closing phandle->download_fd fastboot_okay(phandle, ""); } diff --git a/fastbootd/commands/flash.c b/fastbootd/commands/flash.c index 0954217..5f8b931 100644 --- a/fastbootd/commands/flash.c +++ b/fastbootd/commands/flash.c @@ -39,9 +39,6 @@ #include "utils.h" #include "commands/partitions.h" -#ifdef FLASH_CERT -#include "secure.h" -#endif #define ALLOWED_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-." #define BUFFER_SIZE 1024 * 1024 @@ -115,47 +112,3 @@ int flash_write(int partition_fd, int data_fd, ssize_t size, ssize_t skip) return 0; } - -#ifdef FLASH_CERT - -int flash_validate_certificate(int signed_fd, int *data_fd) { - int ret = 0; - const char *cert_path; - X509_STORE *store = NULL; - CMS_ContentInfo *content_info; - BIO *content; - - cert_path = fastboot_getvar("certificate-path"); - if (!strcmp(cert_path, "")) { - D(ERR, "could not find cert-key value in config file"); - goto finish; - } - - store = cert_store_from_path(cert_path); - if (store == NULL) { - D(ERR, "unable to create certification store"); - goto finish; - } - - if (cert_read(signed_fd, &content_info, &content)) { - D(ERR, "reading data failed"); - goto finish; - } - - ret = cert_verify(content, content_info, store, data_fd); - cert_release(content, content_info); - - return ret; - -finish: - if (store != NULL) - cert_release_store(store); - - return ret; -} - -#else -int flash_validate_certificate(int signed_fd, int *data_fd) { - return 1; -} -#endif diff --git a/fastbootd/commands/flash.h b/fastbootd/commands/flash.h index 86dc811..8ffd688 100644 --- a/fastbootd/commands/flash.h +++ b/fastbootd/commands/flash.h @@ -58,7 +58,5 @@ static inline ssize_t read_data_once(int fd, char *buffer, ssize_t size) { return readcount; } -int flash_validate_certificate(int signed_fd, int *data_fd); - #endif diff --git a/fastbootd/fastbootd.c b/fastbootd/fastbootd.c index 74ff805..90b9ef9 100644 --- a/fastbootd/fastbootd.c +++ b/fastbootd/fastbootd.c @@ -21,7 +21,6 @@ #include "debug.h" #include "trigger.h" -#include "secure.h" unsigned int debug_level = DEBUG; @@ -37,7 +36,6 @@ int main(int argc, char **argv) klog_init(); klog_set_level(6); - cert_init_crypto(); config_init(); load_trigger(); commands_init(); diff --git a/fastbootd/other/sign/src/SignImg.java b/fastbootd/other/sign/src/SignImg.java deleted file mode 100644 index 338d427..0000000 --- a/fastbootd/other/sign/src/SignImg.java +++ /dev/null @@ -1,181 +0,0 @@ -package signtool; - -import java.io.*; -import java.util.Properties; -import java.util.ArrayList; - -import javax.mail.internet.*; -import javax.mail.MessagingException; -import javax.mail.Session; -import javax.activation.MailcapCommandMap; -import javax.activation.CommandMap; - -import java.security.PrivateKey; -import java.security.Security; -import java.security.KeyFactory; -import java.security.KeyStore; -import java.security.NoSuchAlgorithmException; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.InvalidKeySpecException; -import java.security.cert.X509Certificate; -import java.security.cert.CertificateFactory; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CertificateEncodingException; - -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; -import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; -import org.bouncycastle.operator.ContentSigner; -import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import org.bouncycastle.cms.CMSProcessableByteArray; -import org.bouncycastle.cms.CMSSignedGenerator; -import org.bouncycastle.cms.CMSSignedDataGenerator; -import org.bouncycastle.cms.CMSSignedGenerator; -import org.bouncycastle.cms.CMSProcessable; -import org.bouncycastle.cms.CMSSignedData; -import org.bouncycastle.cms.CMSTypedData; -import org.bouncycastle.cert.jcajce.JcaCertStore; -import org.bouncycastle.util.Store; -import org.bouncycastle.asn1.ASN1InputStream; -import org.bouncycastle.asn1.DEROutputStream; -import org.bouncycastle.asn1.ASN1Object; - - -public class SignImg { - - /* It reads private key in pkcs#8 formate - * Conversion: - * openssl pkcs8 -topk8 -nocrypt -outform DER < inkey.pem > outkey.pk8 - */ - private static PrivateKey getPrivateKey(String path) throws IOException, FileNotFoundException, NoSuchAlgorithmException, InvalidKeySpecException { - File file = new File(path); - FileInputStream fis = new FileInputStream(file); - byte[] data = new byte[(int)file.length()]; - fis.read(data); - fis.close(); - - PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(data); - KeyFactory kf = KeyFactory.getInstance("RSA"); - PrivateKey privateKey = kf.generatePrivate(kspec); - - return privateKey; - } - - private static MimeBodyPart getContent(String path) throws IOException, FileNotFoundException, MessagingException { - MimeBodyPart body = new MimeBodyPart(); - - File file = new File(path); - FileInputStream fis = new FileInputStream(file); - byte[] data = new byte[(int)file.length()]; - fis.read(data); - fis.close(); - - body.setContent(data, "application/octet-stream"); - - return body; - } - - private static CMSProcessableByteArray getCMSContent(String path) throws IOException, FileNotFoundException, MessagingException { - File file = new File(path); - FileInputStream fis = new FileInputStream(file); - byte[] data = new byte[(int)file.length()]; - fis.read(data); - fis.close(); - CMSProcessableByteArray cms = new CMSProcessableByteArray(data); - - return cms; - } - - private static X509Certificate readCert(String path) throws IOException, FileNotFoundException, CertificateException { - File file = new File(path); - FileInputStream is = new FileInputStream(file); - - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - Certificate cert = cf.generateCertificate(is); - is.close(); - - return (X509Certificate) cert; - } - - private static void save(MimeBodyPart content, String path) throws IOException, FileNotFoundException, MessagingException { - File file = new File(path); - FileOutputStream os = new FileOutputStream(file); - - content.writeTo(os); - - os.close(); - } - - private static Store certToStore(X509Certificate certificate) throws CertificateEncodingException { - ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>(); - certList.add(certificate); - return new JcaCertStore(certList); - } - - public static void setDefaultMailcap() - { - MailcapCommandMap _mailcap = - (MailcapCommandMap)CommandMap.getDefaultCommandMap(); - - _mailcap.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature"); - _mailcap.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime"); - _mailcap.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature"); - _mailcap.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime"); - _mailcap.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed"); - - CommandMap.setDefaultCommandMap(_mailcap); - } - - public static void main(String[] args) { - try { - if (args.length < 4) { - System.out.println("Usage: signimg data private_key certificate output"); - return; - } - System.out.println("Signing the image"); - setDefaultMailcap(); - - Security.addProvider(new BouncyCastleProvider()); - - PrivateKey key = getPrivateKey(args[1]); - System.out.println("File read sucessfully"); - - CMSSignedDataGenerator generator = new CMSSignedDataGenerator(); - - CMSTypedData body = getCMSContent(args[0]); - System.out.println("Content read sucessfully"); - - X509Certificate cert = (X509Certificate) readCert(args[2]); - System.out.println("Certificate read sucessfully"); - - ContentSigner sha256Signer = new JcaContentSignerBuilder("SHA256withRSA").setProvider("BC").build(key); - - Store certs = certToStore(cert); - - generator.addCertificates(certs); - generator.addSignerInfoGenerator( - new JcaSignerInfoGeneratorBuilder( - new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()) - .build(sha256Signer, cert)); - - CMSSignedData signed = generator.generate(body, true); - System.out.println("Signed"); - - Properties props = System.getProperties(); - Session session = Session.getDefaultInstance(props, null); - - File file = new File(args[3]); - FileOutputStream os = new FileOutputStream(file); - - ASN1InputStream asn1 = new ASN1InputStream(signed.getEncoded()); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - DEROutputStream dOut = new DEROutputStream(os); - dOut.writeObject(ASN1Object.fromByteArray(signed.getEncoded())); - - } - catch (Exception ex) { - System.out.println("Exception during programm execution: " + ex.getMessage()); - } - } -} diff --git a/fastbootd/secure.c b/fastbootd/secure.c deleted file mode 100644 index 75a6f3c..0000000 --- a/fastbootd/secure.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2009-2013, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google, Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - - -#include <openssl/pem.h> -#include <openssl/engine.h> -#include <openssl/x509.h> -#include <openssl/x509v3.h> -#include <openssl/pem.h> -#include <openssl/cms.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -#include "secure.h" -#include "debug.h" -#include "utils.h" - - -void cert_init_crypto() { - CRYPTO_malloc_init(); - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - ENGINE_load_builtin_engines(); -} - -X509_STORE *cert_store_from_path(const char *path) { - - X509_STORE *store; - struct stat st; - X509_LOOKUP *lookup; - - if (stat(path, &st)) { - D(ERR, "Unable to stat cert path"); - goto error; - } - - if (!(store = X509_STORE_new())) { - goto error; - } - - if (S_ISDIR(st.st_mode)) { - lookup = X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir()); - if (lookup == NULL) - goto error; - if (!X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM)) { - D(ERR, "Error loading cert directory %s", path); - goto error; - } - } - else if(S_ISREG(st.st_mode)) { - lookup = X509_STORE_add_lookup(store,X509_LOOKUP_file()); - if (lookup == NULL) - goto error; - if (!X509_LOOKUP_load_file(lookup, path, X509_FILETYPE_PEM)) { - D(ERR, "Error loading cert directory %s", path); - goto error; - } - } - else { - D(ERR, "cert path is not directory or regular file"); - goto error; - } - - return store; - -error: - return NULL; -} - - -int cert_read(int fd, CMS_ContentInfo **content, BIO **output) { - BIO *input; - *output = NULL; - - - input = BIO_new_fd(fd, BIO_NOCLOSE); - if (input == NULL) { - D(ERR, "Unable to open input"); - goto error; - } - - *content = SMIME_read_CMS(input, output); - if (*content == NULL) { - unsigned long err = ERR_peek_last_error(); - D(ERR, "Unable to parse input file: %s", ERR_lib_error_string(err)); - goto error_read; - } - - BIO_free(input); - - return 0; - -error_read: - BIO_free(input); -error: - return 1; -} - -int cert_verify(BIO *content, CMS_ContentInfo *content_info, X509_STORE *store, int *out_fd) { - BIO *output_temp; - int ret; - - *out_fd = create_temp_file(); - if (*out_fd < 0) { - D(ERR, "unable to create temporary file"); - return -1; - } - - output_temp = BIO_new_fd(*out_fd, BIO_NOCLOSE); - if (output_temp == NULL) { - D(ERR, "unable to create temporary bio"); - close(*out_fd); - return -1; - } - - ret = CMS_verify(content_info, NULL ,store, content, output_temp, 0); - - if (ret == 0) { - char buf[256]; - unsigned long err = ERR_peek_last_error(); - D(ERR, "Verification failed with reason: %s, %s", ERR_lib_error_string(err), ERR_error_string(err, buf)); - D(ERR, "Data used: content %d", (int) content); - } - - ERR_clear_error(); - ERR_remove_state(0); - - BIO_free(output_temp); - - return ret; -} - -void cert_release(BIO *content, CMS_ContentInfo *info) { - BIO_free(content); - CMS_ContentInfo_free(info); -} - diff --git a/fastbootd/secure.h b/fastbootd/secure.h deleted file mode 100644 index 878a643..0000000 --- a/fastbootd/secure.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2009-2013, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google, Inc. nor the names of its contributors - * may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _FASTBOOTD_SECURE_H -#define _FASTBOOTD_SECURE_H - -#include <openssl/ssl.h> -#include <openssl/x509.h> -#include <openssl/x509v3.h> -#include <openssl/pem.h> -#include <openssl/cms.h> - -void cert_init_crypto(); - -X509_STORE *cert_store_from_path(const char*stream); - -static inline void cert_release_store(X509_STORE *store) { - X509_STORE_free(store); -} - -int cert_read(int fd, CMS_ContentInfo **content, BIO **output); -int cert_verify(BIO *content, CMS_ContentInfo *content_info, X509_STORE *store, int *out_fd); -void cert_release(BIO *content, CMS_ContentInfo *info); - -#endif diff --git a/fastbootd/utils.c b/fastbootd/utils.c index 8205af4..16e1c09 100644 --- a/fastbootd/utils.c +++ b/fastbootd/utils.c @@ -34,7 +34,6 @@ #include <stdio.h> #include <sys/ioctl.h> #include <linux/fs.h> -#include <stdlib.h> #include "utils.h" #include "debug.h" @@ -146,15 +145,3 @@ int wipe_block_device(int fd, int64_t len) return 0; } -int create_temp_file() { - char tempname[] = "/dev/fastboot_data_XXXXXX"; - int fd; - - fd = mkstemp(tempname); - if (fd < 0) - return -1; - - unlink(tempname); - - return fd; -} diff --git a/fastbootd/utils.h b/fastbootd/utils.h index bc4da25..a553a25 100644 --- a/fastbootd/utils.h +++ b/fastbootd/utils.h @@ -42,7 +42,6 @@ uint64_t get_file_size64(int fd); uint64_t get_file_size(int fd); uint64_t get_block_device_size(int fd); int wipe_block_device(int fd, int64_t len); -int create_temp_file(); #define ROUND_TO_PAGE(address,pagesize) ((address + pagesize - 1) & (~(pagesize - 1))) |