Fix buffer size in pk_write_*_pem()
diff --git a/ChangeLog b/ChangeLog
index 0a7c33f..51c435a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,8 @@
standard defining how to use SHA-2 with SSL 3.0).
* Ciphersuites using RSA-PSK key exchange new require TLS 1.x (the spec is
ambiguous on how to encode some packets with SSL 3.0).
+ * Made buffer size in pk_write_(pub)key_pem() more dynamic, eg smaller if
+ RSA is disabled, larger if POLARSSL_MPI_MAX_SIZE is larger.
= PolarSSL 1.3.8 released 2014-07-11
Security
diff --git a/library/pkwrite.c b/library/pkwrite.c
index 3b0bbdb..d627380 100644
--- a/library/pkwrite.c
+++ b/library/pkwrite.c
@@ -294,10 +294,93 @@
#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
+/*
+ * Max sizes of key per types. Shown as tag + len (+ content).
+ */
+
+#if defined(POLARSSL_RSA_C)
+/*
+ * RSA public keys:
+ * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3
+ * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
+ * + 1 + 1 + 9 (rsa oid)
+ * + 1 + 1 (params null)
+ * subjectPublicKey BIT STRING } 1 + 3 + (1 + below)
+ * RSAPublicKey ::= SEQUENCE { 1 + 3
+ * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1
+ * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1
+ * }
+ */
+#define RSA_PUB_DER_MAX_BYTES 38 + 2 * POLARSSL_MPI_MAX_SIZE
+
+/*
+ * RSA private keys:
+ * RSAPrivateKey ::= SEQUENCE { 1 + 3
+ * version Version, 1 + 1 + 1
+ * modulus INTEGER, 1 + 3 + MPI_MAX + 1
+ * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1
+ * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1
+ * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
+ * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
+ * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
+ * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
+ * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1
+ * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported)
+ * }
+ */
+#define MPI_MAX_SIZE_2 POLARSSL_MPI_MAX_SIZE / 2 + \
+ POLARSSL_MPI_MAX_SIZE % 2
+#define RSA_PRV_DER_MAX_BYTES 47 + 3 * POLARSSL_MPI_MAX_SIZE \
+ + 5 * MPI_MAX_SIZE_2
+
+#else /* POLARSSL_RSA_C */
+
+#define RSA_PUB_DER_MAX_BYTES 0
+#define RSA_PRV_DER_MAX_BYTES 0
+
+#endif /* POLARSSL_RSA_C */
+
+#if defined(POLARSSL_ECP_C)
+/*
+ * EC public keys:
+ * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2
+ * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
+ * + 1 + 1 + 7 (ec oid)
+ * + 1 + 1 + 9 (namedCurve oid)
+ * subjectPublicKey BIT STRING 1 + 2 + 1 [1]
+ * + 1 (point format) [1]
+ * + 2 * ECP_MAX (coords) [1]
+ * }
+ */
+#define ECP_PUB_DER_MAX_BYTES 30 + 2 * POLARSSL_ECP_MAX_BYTES
+
+/*
+ * EC private keys:
+ * ECPrivateKey ::= SEQUENCE { 1 + 2
+ * version INTEGER , 1 + 1 + 1
+ * privateKey OCTET STRING, 1 + 1 + ECP_MAX
+ * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9)
+ * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above
+ * }
+ */
+#define ECP_PRV_DER_MAX_BYTES 29 + 3 * POLARSSL_ECP_MAX_BYTES
+
+#else /* POLARSSL_ECP_C */
+
+#define ECP_PUB_DER_MAX_BYTES 0
+#define ECP_PRV_DER_MAX_BYTES 0
+
+#endif /* POLARSSL_ECP_C */
+
+#define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
+ RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
+#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
+
int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size )
{
int ret;
- unsigned char output_buf[4096];
+ unsigned char output_buf[PUB_DER_MAX_BYTES];
size_t olen = 0;
if( ( ret = pk_write_pubkey_der( key, output_buf,
@@ -319,7 +402,7 @@
int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size )
{
int ret;
- unsigned char output_buf[4096];
+ unsigned char output_buf[PRV_DER_MAX_BYTES];
const char *begin, *end;
size_t olen = 0;
diff --git a/tests/data_files/rsa4096_prv.pem b/tests/data_files/rsa4096_prv.pem
new file mode 100644
index 0000000..b674aa0
--- /dev/null
+++ b/tests/data_files/rsa4096_prv.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
diff --git a/tests/data_files/rsa4096_pub.pem b/tests/data_files/rsa4096_pub.pem
new file mode 100644
index 0000000..15d13d3
--- /dev/null
+++ b/tests/data_files/rsa4096_pub.pem
@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5F2mqEsdntPAEij6HfCY
+nKiLMGnm6PcfsaFYeFYO1EufOjN5ZJP90cr3CrCnN9JOAdpBbTpzA0RcIcAdWBzv
+NNAtIMvSfi22WJYVjzD0Bvs2rCYH76Yc6vfx7y9zXZcanh8S/2t7B64xmxOWL4RE
++f8HWTijAWlyUFDk+DuJWpQK2o0bhE4S8mX+uUl3afNW5CiPsRky1N1v4a7/J2b7
+cG+7pDWUcjnvmNCN84v+gSucXfKg/LiAnZgY7xih2ePEhkkIqn6kU0cVBQj1cZ7h
+XGRaZ/MnqZ2y+KjiuFot2saNk/v0vjjW+xOx76qJV99LtN/1qvCYnO1RqMv2EM8W
+hErLcgiRrihzaz3a2GaumL30CcNixrEXRyEjFaO/klqkpuZRHTtyUnkvhUkPUHuH
+n45XPxZ7a2XRyrSbFyyS0amTjQwQCveSRiJFjK5TZ56CVGKF/DmuLSHeTY3vwi+W
+XVdKMYQ6Zi9jwFJo/S4TRpzp+DTSH68FrFRqE1+qIVyWQjmhWxuvPhqVkG0IT7CZ
+0M8lWesysyI759f5D8DhEp/KbWLDeXWCzcNSbgWGHW5JA+fCV7+8m0PqodIy5D8L
+hwm2tI5dA6Qcro8X127RWVaVsN8LIzdf1THXfnZIm1fDBNUfhXapKfnFV8EvALFX
+2Gy8M3kZQ3slaGegILfqRKcCAwEAAQ==
+-----END PUBLIC KEY-----
diff --git a/tests/suites/test_suite_pkwrite.data b/tests/suites/test_suite_pkwrite.data
index 68adef6..a4d49e7 100644
--- a/tests/suites/test_suite_pkwrite.data
+++ b/tests/suites/test_suite_pkwrite.data
@@ -2,14 +2,38 @@
depends_on:POLARSSL_RSA_C:POLARSSL_BASE64_C
pk_write_pubkey_check:"data_files/server1.pubkey"
-Public key write check EC
+Public key write check RSA 4096
+depends_on:POLARSSL_RSA_C:POLARSSL_BASE64_C
+pk_write_pubkey_check:"data_files/rsa4096_pub.pem"
+
+Public key write check EC 192 bits
depends_on:POLARSSL_ECP_C:POLARSSL_BASE64_C:POLARSSL_ECP_DP_SECP192R1_ENABLED
pk_write_pubkey_check:"data_files/ec_pub.pem"
+Public key write check EC 521 bits
+depends_on:POLARSSL_ECP_C:POLARSSL_BASE64_C:POLARSSL_ECP_DP_SECP521R1_ENABLED
+pk_write_pubkey_check:"data_files/ec_521_pub.pem"
+
+Public key write check EC Brainpool 512 bits
+depends_on:POLARSSL_ECP_C:POLARSSL_BASE64_C:POLARSSL_ECP_DP_BP512R1_ENABLED
+pk_write_pubkey_check:"data_files/ec_bp512_pub.pem"
+
Private key write check RSA
depends_on:POLARSSL_RSA_C:POLARSSL_BASE64_C
pk_write_key_check:"data_files/server1.key"
-Private key write check EC
+Private key write check RSA 4096
+depends_on:POLARSSL_RSA_C:POLARSSL_BASE64_C
+pk_write_key_check:"data_files/rsa4096_prv.pem"
+
+Private key write check EC 192 bits
depends_on:POLARSSL_ECP_C:POLARSSL_BASE64_C:POLARSSL_ECP_DP_SECP192R1_ENABLED
pk_write_key_check:"data_files/ec_prv.sec1.pem"
+
+Private key write check EC 521 bits
+depends_on:POLARSSL_ECP_C:POLARSSL_BASE64_C:POLARSSL_ECP_DP_SECP521R1_ENABLED
+pk_write_key_check:"data_files/ec_521_prv.pem"
+
+Private key write check EC Brainpool 512 bits
+depends_on:POLARSSL_ECP_C:POLARSSL_BASE64_C:POLARSSL_ECP_DP_SECP192R1_ENABLED
+pk_write_key_check:"data_files/ec_bp512_prv.pem"