Fastbootd: flashing certification
Change-Id: I564086908942463eebee69449d484ba03effc50e
This commit is contained in:
parent
bc7cbfd4e3
commit
5ccecfd26d
|
@ -30,6 +30,7 @@ LOCAL_SRC_FILES := \
|
|||
commands/virtual_partitions.c \
|
||||
fastbootd.c \
|
||||
protocol.c \
|
||||
secure.c \
|
||||
transport.c \
|
||||
trigger.c \
|
||||
usb_linux_client.c \
|
||||
|
@ -37,11 +38,12 @@ LOCAL_SRC_FILES := \
|
|||
|
||||
LOCAL_MODULE := fastbootd
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter
|
||||
LOCAL_CFLAGS := -Wall -Werror -Wno-unused-parameter -DFLASH_CERT
|
||||
LOCAL_LDFLAGS := -ldl
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libhardware \
|
||||
libcrypto \
|
||||
libhardware_legacy
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
|
|
|
@ -52,6 +52,8 @@
|
|||
|
||||
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;
|
||||
|
@ -59,9 +61,11 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg)
|
|||
void *ramdisk_ptr;
|
||||
void *second_ptr;
|
||||
struct boot_img_hdr *hdr;
|
||||
int sz, atags_sz, new_atags_sz;
|
||||
int rv;
|
||||
char *ptr = NULL, *atags_ptr = NULL, *new_atags = NULL;
|
||||
char *ptr = NULL;
|
||||
char *atags_ptr = NULL;
|
||||
char *new_atags = NULL;
|
||||
int data_fd = 0;
|
||||
|
||||
D(DEBUG, "cmd_boot %s\n", arg);
|
||||
|
||||
if (phandle->download_fd < 0) {
|
||||
|
@ -75,9 +79,18 @@ static void cmd_boot(struct protocol_handle *phandle, const char *arg)
|
|||
goto error;
|
||||
}
|
||||
|
||||
sz = get_file_size(phandle->download_fd);
|
||||
// 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);
|
||||
|
||||
ptr = (char *) mmap(NULL, sz, PROT_READ,
|
||||
MAP_POPULATE | MAP_PRIVATE, phandle->download_fd, 0);
|
||||
MAP_POPULATE | MAP_PRIVATE, data_fd, 0);
|
||||
|
||||
hdr = (struct boot_img_hdr *) ptr;
|
||||
|
||||
if (ptr == MAP_FAILED) {
|
||||
|
@ -130,6 +143,7 @@ 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);
|
||||
|
@ -256,6 +270,7 @@ 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);
|
||||
|
||||
|
@ -273,9 +288,14 @@ 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(phandle->download_fd, data, BOOT_MAGIC_SIZE) < BOOT_MAGIC_SIZE) {
|
||||
if (read_data_once(data_fd, data, BOOT_MAGIC_SIZE) < BOOT_MAGIC_SIZE) {
|
||||
fastboot_fail(phandle, "incoming data read error, cannot read boot header");
|
||||
return;
|
||||
}
|
||||
|
@ -287,7 +307,10 @@ static void cmd_flash(struct protocol_handle *phandle, const char *arg)
|
|||
|
||||
partition = flash_get_partiton(path);
|
||||
|
||||
sz = get_file_size64(phandle->download_fd);
|
||||
sz = get_file_size64(data_fd);
|
||||
|
||||
sz -= header_sz;
|
||||
|
||||
if (sz > get_file_size64(partition)) {
|
||||
flash_close(partition);
|
||||
D(WARN, "size of file too large");
|
||||
|
@ -304,6 +327,8 @@ 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, "");
|
||||
}
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
#include "utils.h"
|
||||
#include "commands/partitions.h"
|
||||
|
||||
#ifdef FLASH_CERT
|
||||
#include "secure.h"
|
||||
#endif
|
||||
|
||||
#define ALLOWED_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-."
|
||||
#define BUFFER_SIZE 1024 * 1024
|
||||
|
@ -112,3 +115,47 @@ 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
|
||||
|
|
|
@ -58,5 +58,7 @@ 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
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "debug.h"
|
||||
#include "trigger.h"
|
||||
#include "secure.h"
|
||||
|
||||
unsigned int debug_level = DEBUG;
|
||||
|
||||
|
@ -36,6 +37,7 @@ int main(int argc, char **argv)
|
|||
klog_init();
|
||||
klog_set_level(6);
|
||||
|
||||
cert_init_crypto();
|
||||
config_init();
|
||||
load_trigger();
|
||||
commands_init();
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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
|
|
@ -34,6 +34,7 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/fs.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "debug.h"
|
||||
|
@ -145,3 +146,15 @@ 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;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ 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)))
|
||||
|
||||
|
|
Loading…
Reference in New Issue