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

Add PKCS8 writing support #1759

Closed
wants to merge 4 commits into from
Closed
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
11 changes: 11 additions & 0 deletions include/mbedtls/pk.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,17 @@ int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *ctx, unsigned char *buf, si
* \return 0 if successful, or a specific error code
*/
int mbedtls_pk_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );

/**
* \brief Write a private key to a PKCS#8 or SEC8 PEM string
*
* \param ctx private to write away
* \param buf buffer to write to
* \param size size of the buffer
*
* \return 0 if successful, or a specific error code
*/
int mbedtls_pkcs8_write_key_pem( mbedtls_pk_context *ctx, unsigned char *buf, size_t size );
#endif /* MBEDTLS_PEM_WRITE_C */
#endif /* MBEDTLS_PK_WRITE_C */

Expand Down
75 changes: 75 additions & 0 deletions library/pkwrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,9 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"

#define PEM_BEGIN_PRIVATE_KEY "-----BEGIN PRIVATE KEY-----\n"
#define PEM_END_PRIVATE_KEY "-----END PRIVATE KEY-----\n"

#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n"
#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
Expand Down Expand Up @@ -451,6 +454,19 @@ int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_
#define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES

/*
* PKCS8 envelope:
* PrivateKeyInfo ::= SEQUENCE {
* version Version,
* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
* privateKey PrivateKey,
* attributes [0] IMPLICIT Attributes OPTIONAL }
* }
*/

#define PRV_PKCS8_DER_MAX_BYTES 22 + PRV_DER_MAX_BYTES
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please document where the +22 comes from? Perhaps annotate the PrivateKeyInfo structure similar to https://github.com/ARMmbed/mbedtls/pull/1759/files#diff-788a5101fe2618b1e14eb09a62e1d7ecR436



int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{
int ret;
Expand Down Expand Up @@ -510,6 +526,65 @@ int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_

return( 0 );
}

int mbedtls_pkcs8_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size )
{
int ret;
unsigned char output_buf[PRV_PKCS8_DER_MAX_BYTES];
const char *begin = PEM_BEGIN_PRIVATE_KEY;
const char *end = PEM_END_PRIVATE_KEY;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it would be ideal if we used the header and footer for RSA or EC as in mbedtls_pk_write_key_pem().

size_t olen = 0;
unsigned char *c;
int len = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Its a length, should it be size_t?

const char *oid;
size_t oid_len;

if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: Please add spaces before ) and after (.

return( ret );
#if defined(MBEDTLS_RSA_C)
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA )
{
}
else
#endif
#if defined(MBEDTLS_ECP_C)
if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY )
{
}
else
#endif
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: Please add matching comment to the #endif. For example, here it would be:

#endif /* MBEDTLS_ECP_C */

return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE );

len = ret;
c = output_buf + sizeof(output_buf) - len;
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: Please add spaces before ) and after (.


/* Wrap PKCS1 key in OCTET STRING */
Copy link
Contributor

Choose a reason for hiding this comment

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

PKCS1?

MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, output_buf, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, output_buf, MBEDTLS_ASN1_OCTET_STRING ) );

/* privateKeyAlgorithm */
if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ),
&oid, &oid_len ) ) != 0 )
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use spaces instead of tabs

return ret;
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: Please add brackets around the return argument as required by the Mbed TLS coding standards.

MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier(&c, output_buf, oid, oid_len, 0) );
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: Please add spaces before ) and after (


/* version */
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, output_buf, 0 ) );

/* sequence and length */
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, output_buf, len ) );
MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, output_buf, MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE ) );
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: Please replace tabs with spaces.


if( ( ret = mbedtls_pem_write_buffer( begin, end,
output_buf + sizeof(output_buf) - len,
Copy link
Contributor

Choose a reason for hiding this comment

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

Minor: Please add spaces before ) and after (

len, buf, size, &olen ) ) != 0 )
{
return( ret );
}

return( 0 );
}
#endif /* MBEDTLS_PEM_WRITE_C */

#endif /* MBEDTLS_PK_WRITE_C */
17 changes: 14 additions & 3 deletions programs/pkey/gen_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ int dev_random_entropy_poll( void *data, unsigned char *output,

#define FORMAT_PEM 0
#define FORMAT_DER 1
#define FORMAT_PEM_PKCS8 2

#define DFL_TYPE MBEDTLS_PK_RSA
#define DFL_RSA_KEYSIZE 4096
Expand Down Expand Up @@ -154,10 +155,18 @@ static int write_private_key( mbedtls_pk_context *key, const char *output_file )
size_t len = 0;

memset(output_buf, 0, 16000);
if( opt.format == FORMAT_PEM )
if( opt.format == FORMAT_PEM || opt.format == FORMAT_PEM_PKCS8)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add space before the )

{
if( ( ret = mbedtls_pk_write_key_pem( key, output_buf, 16000 ) ) != 0 )
return( ret );
if (opt.format == FORMAT_PEM_PKCS8)
{
if( ( ret = mbedtls_pkcs8_write_key_pem( key, output_buf, 16000 ) ) != 0 )
return( ret );
}
else
{
if( ( ret = mbedtls_pk_write_key_pem( key, output_buf, 16000 ) ) != 0 )
return( ret );
}

len = strlen( (char *) output_buf );
}
Expand Down Expand Up @@ -255,6 +264,8 @@ int main( int argc, char *argv[] )
opt.format = FORMAT_PEM;
else if( strcmp( q, "der" ) == 0 )
opt.format = FORMAT_DER;
else if( strcmp( q, "pkcs8" ) == 0 )
opt.format = FORMAT_PEM_PKCS8;
else
goto usage;
}
Expand Down