Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[image] Add the "imgtrust" and "imgverify" commands
Signed-off-by: Michael Brown <mcb30@ipxe.org>
- Loading branch information
Showing
6 changed files
with
275 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
/* | ||
* Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License as | ||
* published by the Free Software Foundation; either version 2 of the | ||
* License, or any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, but | ||
* WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
*/ | ||
|
||
FILE_LICENCE ( GPL2_OR_LATER ); | ||
|
||
#include <stdint.h> | ||
#include <stdio.h> | ||
#include <getopt.h> | ||
#include <ipxe/image.h> | ||
#include <ipxe/command.h> | ||
#include <ipxe/parseopt.h> | ||
#include <usr/imgmgmt.h> | ||
#include <usr/imgtrust.h> | ||
|
||
/** @file | ||
* | ||
* Image trust management commands | ||
* | ||
*/ | ||
|
||
/** "imgtrust" options */ | ||
struct imgtrust_options { | ||
/** Allow trusted images */ | ||
int allow; | ||
/** Make trust requirement permanent */ | ||
int permanent; | ||
}; | ||
|
||
/** "imgtrust" option list */ | ||
static struct option_descriptor imgtrust_opts[] = { | ||
OPTION_DESC ( "allow", 'a', no_argument, | ||
struct imgtrust_options, allow, parse_flag ), | ||
OPTION_DESC ( "permanent", 'p', no_argument, | ||
struct imgtrust_options, permanent, parse_flag ), | ||
}; | ||
|
||
/** "imgtrust" command descriptor */ | ||
static struct command_descriptor imgtrust_cmd = | ||
COMMAND_DESC ( struct imgtrust_options, imgtrust_opts, 0, 0, | ||
"[--allow] [--permanent]" ); | ||
|
||
/** | ||
* The "imgtrust" command | ||
* | ||
* @v argc Argument count | ||
* @v argv Argument list | ||
* @ret rc Return status code | ||
*/ | ||
static int imgtrust_exec ( int argc, char **argv ) { | ||
struct imgtrust_options opts; | ||
int rc; | ||
|
||
/* Parse options */ | ||
if ( ( rc = parse_options ( argc, argv, &imgtrust_cmd, &opts ) ) != 0 ) | ||
return rc; | ||
|
||
/* Set trust requirement */ | ||
if ( ( rc = image_set_trust ( ( ! opts.allow ), | ||
opts.permanent ) ) != 0 ) { | ||
printf ( "Could not set image trust requirement: %s\n", | ||
strerror ( rc ) ); | ||
return rc; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
/** "imgverify" options */ | ||
struct imgverify_options { | ||
/** Required signer common name */ | ||
const char *signer; | ||
/** Keep signature after verification */ | ||
int keep; | ||
}; | ||
|
||
/** "imgverify" option list */ | ||
static struct option_descriptor imgverify_opts[] = { | ||
OPTION_DESC ( "signer", 's', required_argument, | ||
struct imgverify_options, signer, parse_string ), | ||
OPTION_DESC ( "keep", 'k', no_argument, | ||
struct imgverify_options, keep, parse_flag ), | ||
}; | ||
|
||
/** "imgverify" command descriptor */ | ||
static struct command_descriptor imgverify_cmd = | ||
COMMAND_DESC ( struct imgverify_options, imgverify_opts, 2, 2, | ||
"[--signer <signer>] [--keep] <uri|image> " | ||
"<signature uri|image>" ); | ||
|
||
/** | ||
* The "imgverify" command | ||
* | ||
* @v argc Argument count | ||
* @v argv Argument list | ||
* @ret rc Return status code | ||
*/ | ||
static int imgverify_exec ( int argc, char **argv ) { | ||
struct imgverify_options opts; | ||
const char *image_name_uri; | ||
const char *signature_name_uri; | ||
struct image *image; | ||
struct image *signature; | ||
int rc; | ||
|
||
/* Parse options */ | ||
if ( ( rc = parse_options ( argc, argv, &imgverify_cmd, &opts ) ) != 0 ) | ||
return rc; | ||
|
||
/* Parse image name/URI string */ | ||
image_name_uri = argv[optind]; | ||
|
||
/* Parse signature name/URI string */ | ||
signature_name_uri = argv[ optind + 1 ]; | ||
|
||
/* Acquire the image */ | ||
if ( ( rc = imgacquire ( image_name_uri, &image ) ) != 0 ) | ||
goto err_acquire_image; | ||
|
||
/* Acquire the signature image */ | ||
if ( ( rc = imgacquire ( signature_name_uri, &signature ) ) != 0 ) | ||
goto err_acquire_signature; | ||
|
||
/* Verify image */ | ||
if ( ( rc = imgverify ( image, signature, opts.signer ) ) != 0 ) { | ||
printf ( "Could not verify: %s\n", strerror ( rc ) ); | ||
goto err_verify; | ||
} | ||
|
||
/* Success */ | ||
rc = 0; | ||
|
||
err_verify: | ||
/* Discard signature unless --keep was specified */ | ||
if ( ! opts.keep ) | ||
unregister_image ( signature ); | ||
err_acquire_signature: | ||
err_acquire_image: | ||
return rc; | ||
} | ||
|
||
/** Image trust management commands */ | ||
struct command image_trust_commands[] __command = { | ||
{ | ||
.name = "imgtrust", | ||
.exec = imgtrust_exec, | ||
}, | ||
{ | ||
.name = "imgverify", | ||
.exec = imgverify_exec, | ||
}, | ||
}; | ||
|
||
/* Drag in objects typically required for signature verification */ | ||
REQUIRE_OBJECT ( rsa ); | ||
REQUIRE_OBJECT ( md5 ); | ||
REQUIRE_OBJECT ( sha1 ); | ||
REQUIRE_OBJECT ( sha256 ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#ifndef _USR_IMGTRUST_H | ||
#define _USR_IMGTRUST_H | ||
|
||
/** @file | ||
* | ||
* Image trust management | ||
* | ||
*/ | ||
|
||
FILE_LICENCE ( GPL2_OR_LATER ); | ||
|
||
#include <ipxe/image.h> | ||
|
||
extern int imgverify ( struct image *image, struct image *signature, | ||
const char *name ); | ||
|
||
#endif /* _USR_IMGTRUST_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
* Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License as | ||
* published by the Free Software Foundation; either version 2 of the | ||
* License, or any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, but | ||
* WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
*/ | ||
|
||
FILE_LICENCE ( GPL2_OR_LATER ); | ||
|
||
#include <stdlib.h> | ||
#include <errno.h> | ||
#include <time.h> | ||
#include <ipxe/uaccess.h> | ||
#include <ipxe/image.h> | ||
#include <ipxe/cms.h> | ||
#include <usr/imgtrust.h> | ||
|
||
/** @file | ||
* | ||
* Image trust management | ||
* | ||
*/ | ||
|
||
/** | ||
* Verify image using downloaded signature | ||
* | ||
* @v image Image to verify | ||
* @v signature Image containing signature | ||
* @v name Required common name, or NULL to allow any name | ||
* @ret rc Return status code | ||
*/ | ||
int imgverify ( struct image *image, struct image *signature, | ||
const char *name ) { | ||
size_t len; | ||
void *data; | ||
struct cms_signature sig; | ||
time_t now; | ||
int rc; | ||
|
||
/* Mark image as untrusted */ | ||
image_untrust ( image ); | ||
|
||
/* Copy signature to internal memory */ | ||
len = signature->len; | ||
data = malloc ( len ); | ||
if ( ! data ) { | ||
rc = -ENOMEM; | ||
goto err_alloc; | ||
} | ||
copy_from_user ( data, signature->data, 0, len ); | ||
|
||
/* Parse signature */ | ||
if ( ( rc = cms_parse ( &sig, data, len ) ) != 0 ) | ||
goto err_parse; | ||
|
||
/* Use signature to verify image */ | ||
now = time ( NULL ); | ||
if ( ( rc = cms_verify ( &sig, image->data, image->len, | ||
name, now, NULL ) ) != 0 ) | ||
goto err_verify; | ||
|
||
/* Mark image as trusted */ | ||
image_trust ( image ); | ||
|
||
err_verify: | ||
err_parse: | ||
free ( data ); | ||
err_alloc: | ||
return rc; | ||
} |