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

Pkcs7 pr4 #3

Open
wants to merge 5 commits into
base: mbedtls-2.16
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/mbedtls/check_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,12 @@
#error "MBEDTLS_HAVE_INT32/MBEDTLS_HAVE_INT64 and MBEDTLS_HAVE_ASM cannot be defined simultaneously"
#endif /* (MBEDTLS_HAVE_INT32 || MBEDTLS_HAVE_INT64) && MBEDTLS_HAVE_ASM */

#if ( ( defined(MBEDTLS_PKCS7_C) ) && ( !defined(MBEDTLS_ASN1_PARSE_C) ) && \
( !defined(MBEDTLS_OID_C) ) && ( !defined(MBEDTLD_PK_PARSE_C) ) && \
( !defined(MBEDTLS_X509_CRT_PARSE_C) ) && ( !defined(MBEDTLS_BIGNUM_C) ) )
#error "MBEDTLS_PKCS7_C is defined, but not all prerequisites"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will only error if you have none of the prerequisites. Should it be:


#if ( defined(MBEDTLS_PKCS7_C) ) && ( ( !defined(MBEDTLS_ASN1_PARSE_C) ) || \
    ( !defined(MBEDTLS_OID_C) ) || ( !defined(MBEDTLD_PK_PARSE_C) ) || \
    ( !defined(MBEDTLS_X509_CRT_PARSE_C) ) || ( !defined(MBEDTLS_BIGNUM_C) ) )

?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for catching it. Fixed.

#endif

/*
* Avoid warning from -pedantic. This is a convenient place for this
* workaround since this is included by every single file before the
Expand Down
15 changes: 15 additions & 0 deletions include/mbedtls/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -2719,6 +2719,21 @@
*/
#define MBEDTLS_PKCS5_C

/**
* \def MBEDTLS_PKCS7_C
*
* Enable PKCS7 core for using PKCS7 formatted signatures.
* RFC Link - https://tools.ietf.org/html/rfc2315
*
* Module: library/pkcs7.c
*
* Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C,
* MBEDTLS_X509_CRT_PARSE_C MBEDTLS_X509_CRL_PARSE_C, MBEDTLS_ERROR_C
*
* This module is required for the PKCS7 parsing modules.
*/
#define MBEDTLS_PKCS7_C

/**
* \def MBEDTLS_PKCS11_C
*
Expand Down
1 change: 1 addition & 0 deletions include/mbedtls/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
* CIPHER 6 8
* SSL 6 23 (Started from top)
* SSL 7 32
* PKCS7 5 12 (Started from 0x5300)
*
* Module dependent error code (5 bits 0x.00.-0x.F8.)
*/
Expand Down
11 changes: 11 additions & 0 deletions include/mbedtls/oid.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@
#define MBEDTLS_OID_PKCS MBEDTLS_OID_RSA_COMPANY "\x01" /**< pkcs OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) 1 } */
#define MBEDTLS_OID_PKCS1 MBEDTLS_OID_PKCS "\x01" /**< pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 } */
#define MBEDTLS_OID_PKCS5 MBEDTLS_OID_PKCS "\x05" /**< pkcs-5 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 } */
#define MBEDTLS_OID_PKCS7 MBEDTLS_OID_PKCS "\x07" /**< pkcs-7 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 7 } */
#define MBEDTLS_OID_PKCS9 MBEDTLS_OID_PKCS "\x09" /**< pkcs-9 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } */
#define MBEDTLS_OID_PKCS12 MBEDTLS_OID_PKCS "\x0c" /**< pkcs-12 OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 12 } */

Expand Down Expand Up @@ -299,6 +300,16 @@
#define MBEDTLS_OID_PKCS5_PBE_SHA1_DES_CBC MBEDTLS_OID_PKCS5 "\x0a" /**< pbeWithSHA1AndDES-CBC OBJECT IDENTIFIER ::= {pkcs-5 10} */
#define MBEDTLS_OID_PKCS5_PBE_SHA1_RC2_CBC MBEDTLS_OID_PKCS5 "\x0b" /**< pbeWithSHA1AndRC2-CBC OBJECT IDENTIFIER ::= {pkcs-5 11} */

/*
* PKCS#7 OIDs
*/
#define MBEDTLS_OID_PKCS7_DATA MBEDTLS_OID_PKCS7 "\x01" /**< Content type is Data OBJECT IDENTIFIER ::= {pkcs-7 1} */
#define MBEDTLS_OID_PKCS7_SIGNED_DATA MBEDTLS_OID_PKCS7 "\x02" /**< Content type is Signed Data OBJECT IDENTIFIER ::= {pkcs-7 2} */
#define MBEDTLS_OID_PKCS7_ENVELOPED_DATA MBEDTLS_OID_PKCS7 "\x03" /**< Content type is Enveloped Data OBJECT IDENTIFIER ::= {pkcs-7 3} */
#define MBEDTLS_OID_PKCS7_SIGNED_AND_ENVELOPED_DATA MBEDTLS_OID_PKCS7 "\x04" /**< Content type is Signed and Enveloped Data OBJECT IDENTIFIER ::= {pkcs-7 4} */
#define MBEDTLS_OID_PKCS7_DIGESTED_DATA MBEDTLS_OID_PKCS7 "\x05" /**< Content type is Digested Data OBJECT IDENTIFIER ::= {pkcs-7 5} */
#define MBEDTLS_OID_PKCS7_ENCRYPTED_DATA MBEDTLS_OID_PKCS7 "\x06" /**< Content type is Encrypted Data OBJECT IDENTIFIER ::= {pkcs-7 6} */

/*
* PKCS#8 OIDs
*/
Expand Down
227 changes: 227 additions & 0 deletions include/mbedtls/pkcs7.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
/**
* \file pkcs7.h
*
* \brief PKCS7 generic defines and structures
*/
/*
* Copyright (C) 2019, IBM Corp, All Rights Reserved
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#ifndef MBEDTLS_PKCS7_H
#define MBEDTLS_PKCS7_H

#if !defined(MBEDTLS_CONFIG_FILE)
#include "config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

#include "asn1.h"
#include "x509.h"
#include "x509_crt.h"

/**
* \name PKCS7 Module Error codes
* \{
*/
#define MBEDTLS_ERR_PKCS7_INVALID_FORMAT -0x5300 /**< The format is invalid, e.g. different type expected. */
#define MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE -0x53F0 /**< Unavailable feature, e.g. anything other than signed data. */
#define MBEDTLS_ERR_PKCS7_INVALID_VERSION -0x5400 /**< The PKCS7 version element is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO -0x54F0 /**< The PKCS7 content info invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_ALG -0x5500 /**< The algorithm tag or value is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_CERT -0x55F0 /**< The certificate tag or value is invalid or cannot be parsed. */
#define MBEDTLS_ERR_PKCS7_INVALID_SIGNATURE -0x5600 /**< Error parsing the signature */
#define MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO -0x56F0 /**< Error parsing the signer's info */
#define MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA -0x5700 /**< Input invalid. */
#define MBEDTLS_ERR_PKCS7_ALLOC_FAILED -0x57F0 /**< Allocation of memory failed. */
#define MBEDTLS_ERR_PKCS7_FILE_IO_ERROR -0x5800 /**< File Read/Write Error */
#define MBEDTLS_ERR_PKCS7_VERIFY_FAIL -0x58F0 /**< Verification Failed */
/* \} name */

/**
* \name PKCS7 Supported Version
* \{
*/
#define MBEDTLS_PKCS7_SUPPORTED_VERSION 0x01
/* \} name */

#ifdef __cplusplus
extern "C" {
#endif

/**
* Type-length-value structure that allows for ASN1 using DER.
*/
typedef mbedtls_asn1_buf mbedtls_pkcs7_buf;

/**
* Container for ASN1 named information objects.
* It allows for Relative Distinguished Names (e.g. cn=localhost,ou=code,etc.).
*/
typedef mbedtls_asn1_named_data mbedtls_pkcs7_name;

/**
* Container for a sequence of ASN.1 items
*/
typedef mbedtls_asn1_sequence mbedtls_pkcs7_sequence;

/**
* PKCS7 types
*/
typedef enum {
MBEDTLS_PKCS7_NONE=0,
MBEDTLS_PKCS7_DATA,
MBEDTLS_PKCS7_SIGNED_DATA,
MBEDTLS_PKCS7_ENVELOPED_DATA,
MBEDTLS_PKCS7_SIGNED_AND_ENVELOPED_DAYA,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DATA, not DAYA :)

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super catch. Thanks :-)

MBEDTLS_PKCS7_DIGESTED_DATA,
MBEDTLS_PKCS7_ENCRYPTED_DATA,
}
mbedtls_pkcs7_type;

/**
* Structure holding PKCS7 signer info
*/
typedef struct mbedtls_pkcs7_signer_info
{
int version;
mbedtls_x509_buf serial;
mbedtls_x509_name issuer;
mbedtls_x509_buf issuer_raw;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Do we need to store issuer_raw if we also have issuer?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm probably no.. I actually added it very initially.. I will recheck it and remove if not needed.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I kept it for the reason it is in x509_crt.h
mbedtls_x509_buf issuer_raw; /**< The raw issuer data (DER). Used for quick comparison. */

I think since signer and issuer are supposed to be unique, and might be used for checks, I thought to keep it for reason of quick comparision.

With that I am not removing it.

Thanks & Regards,
- Nayna

mbedtls_x509_buf alg_identifier;
mbedtls_x509_buf sig_alg_identifier;
mbedtls_x509_buf sig;
struct mbedtls_pkcs7_signer_info *next;
}
mbedtls_pkcs7_signer_info;

/**
* Structure holding attached data as part of PKCS7 signed data format
*/
typedef struct mbedtls_pkcs7_data
{
mbedtls_pkcs7_buf oid;
mbedtls_pkcs7_buf data;
}
mbedtls_pkcs7_data;

/**
* Structure holding the signed data section
*/
typedef struct mbedtls_pkcs7_signed_data
{
int version;
mbedtls_pkcs7_buf digest_alg_identifiers;
struct mbedtls_pkcs7_data content;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You just established a typedef for this: should you use the typedef instead of the full struct name?

mbedtls_x509_crt certs;
mbedtls_x509_crl crl;
struct mbedtls_pkcs7_signer_info signers;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise.

}
mbedtls_pkcs7_signed_data;

/**
* Structure holding PKCS7 structure, only signed data for now
*/
typedef struct mbedtls_pkcs7
{
mbedtls_pkcs7_buf content_type_oid;
struct mbedtls_pkcs7_signed_data signed_data;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Likewise.

}
mbedtls_pkcs7;

/**
* \brief Initialize pkcs7 structure.
*
* \param pkcs7 pkcs7 structure.
*/
void mbedtls_pkcs7_init( mbedtls_pkcs7 *pkcs7 );

/**
* \brief Parse a single DER formatted pkcs7 content.
*
* \param buf The buffer holding the DER encoded pkcs7.
* \param buflen The size in Bytes of \p buf.
*
* \note This function makes an internal copy of the PKCS7 buffer
* \p buf. In particular, \p buf may be destroyed or reused
* after this call returns.
*
* \return \c 0, if successful.
* \return A negative error code on failure.
*/
int mbedtls_pkcs7_parse_der( const unsigned char *buf, const int buflen,
mbedtls_pkcs7 *pkcs7 );

/**
* \brief Verification of PKCS7 signature.
*
* \param pkcs7 PKCS7 structure containing signature.
* \param cert Certificate containing key to verify signature.
* \param data Plain data on which signature has to be verified.
* \param datalen Length of the data.
*
* \note This function internally calculates the hash on the supplied
* plain data for signature verification.
*
* \return A negative error code on failure.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this and the other functions have * \return \c 0, if successful. like mbedtls_pkcs7_parse_der?

*/
int mbedtls_pkcs7_signed_data_verify( mbedtls_pkcs7 *pkcs7,
mbedtls_x509_crt *cert,
const unsigned char *data,
size_t datalen );

/**
* \brief Verification of PKCS7 signature.
*
* \param pkcs7 PKCS7 structure containing signature.
* \param cert Certificate containing key to verify signature.
* \param hash Hash of the plain data on which signature has to be verified.
* \param hashlen Length of the hash.
*
* \note This function is different from mbedtls_pkcs7_signed_data_verify()
* in a way that it directly recieves the hash of the data.
*
* \return A negative error code on failure.
*/
int mbedtls_pkcs7_signed_hash_verify( mbedtls_pkcs7 *pkcs7,
mbedtls_x509_crt *cert,
const unsigned char *hash, int hashlen);

/**
* \brief Reads the PKCS7 data from the file in a buffer.
*
* \param path Path of the file.
* \param buf Buffer to store the PKCS7 contents from the file.
* \param n Size of the buffer (the contents read from the file).
*
* \return A negative error code on failure.
*/
int mbedtls_pkcs7_load_file( const char *path, unsigned char **buf, size_t *n );

/**
* \brief Unallocate all PKCS7 data and zeroize the memory.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think 'deallocate' might be better - I'm not sure 'unallocate' is a verb. (Unallocated is a word, but I don't think unallocate is.)

* It doesn't free pkcs7 itself. It should be done by the caller.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be \p pkcs7 to indicate it's a parameter?

*
* \param pkcs7 PKCS7 structure to free.
*/
void mbedtls_pkcs7_free( mbedtls_pkcs7 *pkcs7 );

#ifdef __cplusplus
}
#endif

#endif /* pkcs7.h */
3 changes: 2 additions & 1 deletion library/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \

OBJS_X509= certs.o pkcs11.o x509.o \
x509_create.o x509_crl.o x509_crt.o \
x509_csr.o x509write_crt.o x509write_csr.o
x509_csr.o x509write_crt.o x509write_csr.o \
pkcs7.o

OBJS_TLS= debug.o net_sockets.o \
ssl_cache.o ssl_ciphersuites.o \
Expand Down
31 changes: 31 additions & 0 deletions library/error.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@
#include "mbedtls/pkcs5.h"
#endif

#if defined(MBEDTLS_PKCS7_C)
#include "mbedtls/pkcs7.h"
#endif

#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#endif
Expand Down Expand Up @@ -415,6 +419,33 @@ void mbedtls_strerror( int ret, char *buf, size_t buflen )
mbedtls_snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" );
#endif /* MBEDTLS_PKCS5_C */

#if defined(MBEDTLS_PKCS7_C)
if( use_ret == -(MBEDTLS_ERR_PKCS7_INVALID_FORMAT) )
mbedtls_snprintf( buf, buflen, "PKCS7 - The format is invalid, e.g. different type expected" );
if( use_ret == -(MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE) )
mbedtls_snprintf( buf, buflen, "PKCS7 - Unavailable feature, e.g. anything other than signed data" );
if( use_ret == -(MBEDTLS_ERR_PKCS7_INVALID_VERSION) )
mbedtls_snprintf( buf, buflen, "PKCS7 - The PKCS7 version element is invalid or cannot be parsed" );
if( use_ret == -(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO) )
mbedtls_snprintf( buf, buflen, "PKCS7 - The PKCS7 content info invalid or cannot be parsed" );
if( use_ret == -(MBEDTLS_ERR_PKCS7_INVALID_ALG) )
mbedtls_snprintf( buf, buflen, "PKCS7 - The algorithm tag or value is invalid or cannot be parsed" );
if( use_ret == -(MBEDTLS_ERR_PKCS7_INVALID_CERT) )
mbedtls_snprintf( buf, buflen, "PKCS7 - The certificate tag or value is invalid or cannot be parsed" );
if( use_ret == -(MBEDTLS_ERR_PKCS7_INVALID_SIGNATURE) )
mbedtls_snprintf( buf, buflen, "PKCS7 - Error parsing the signature" );
if( use_ret == -(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO) )
mbedtls_snprintf( buf, buflen, "PKCS7 - Error parsing the signer's info" );
if( use_ret == -(MBEDTLS_ERR_PKCS7_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "PKCS7 - Input invalid" );
if( use_ret == -(MBEDTLS_ERR_PKCS7_ALLOC_FAILED) )
mbedtls_snprintf( buf, buflen, "PKCS7 - Allocation of memory failed" );
if( use_ret == -(MBEDTLS_ERR_PKCS7_FILE_IO_ERROR) )
mbedtls_snprintf( buf, buflen, "PKCS7 - File Read/Write Error" );
if( use_ret == -(MBEDTLS_ERR_PKCS7_VERIFY_FAIL) )
mbedtls_snprintf( buf, buflen, "PKCS7 - Verification Failed" );
#endif /* MBEDTLS_PKCS7_C */

#if defined(MBEDTLS_RSA_C)
if( use_ret == -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA) )
mbedtls_snprintf( buf, buflen, "RSA - Bad input parameters to function" );
Expand Down
Loading