Index: openssl/crypto/evp/evp_aead.c |
diff --git a/openssl/crypto/x509/x509_set.c b/openssl/crypto/evp/evp_aead.c |
similarity index 51% |
copy from openssl/crypto/x509/x509_set.c |
copy to openssl/crypto/evp/evp_aead.c |
index 4b94fc58477f68af554a0698f685ec99fc434bb9..91da561f68a30fc9355b5153d5d23a300f78321b 100644 |
--- a/openssl/crypto/x509/x509_set.c |
+++ b/openssl/crypto/evp/evp_aead.c |
@@ -1,4 +1,3 @@ |
-/* crypto/x509/x509_set.c */ |
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
* All rights reserved. |
* |
@@ -56,95 +55,138 @@ |
* [including the GNU Public Licence.] |
*/ |
-#include <stdio.h> |
-#include "cryptlib.h" |
-#include <openssl/asn1.h> |
-#include <openssl/objects.h> |
+#include <limits.h> |
+#include <string.h> |
+ |
#include <openssl/evp.h> |
-#include <openssl/x509.h> |
+#include <openssl/err.h> |
-int X509_set_version(X509 *x, long version) |
+#include "evp_locl.h" |
+ |
+size_t EVP_AEAD_key_length(const EVP_AEAD *aead) |
{ |
- if (x == NULL) return(0); |
- if (x->cert_info->version == NULL) |
- { |
- if ((x->cert_info->version=M_ASN1_INTEGER_new()) == NULL) |
- return(0); |
- } |
- return(ASN1_INTEGER_set(x->cert_info->version,version)); |
+ return aead->key_len; |
} |
-int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) |
+size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead) |
{ |
- ASN1_INTEGER *in; |
+ return aead->nonce_len; |
+ } |
- if (x == NULL) return(0); |
- in=x->cert_info->serialNumber; |
- if (in != serial) |
+size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead) |
+ { |
+ return aead->overhead; |
+ } |
+ |
+size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead) |
+ { |
+ return aead->max_tag_len; |
+ } |
+ |
+int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, |
+ const unsigned char *key, size_t key_len, |
+ size_t tag_len, ENGINE *impl) |
+ { |
+ ctx->aead = aead; |
+ if (key_len != aead->key_len) |
{ |
- in=M_ASN1_INTEGER_dup(serial); |
- if (in != NULL) |
- { |
- M_ASN1_INTEGER_free(x->cert_info->serialNumber); |
- x->cert_info->serialNumber=in; |
- } |
+ EVPerr(EVP_F_EVP_AEAD_CTX_INIT,EVP_R_UNSUPPORTED_KEY_SIZE); |
+ return 0; |
} |
- return(in != NULL); |
+ return aead->init(ctx, key, key_len, tag_len); |
} |
-int X509_set_issuer_name(X509 *x, X509_NAME *name) |
+void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx) |
{ |
- if ((x == NULL) || (x->cert_info == NULL)) return(0); |
- return(X509_NAME_set(&x->cert_info->issuer,name)); |
+ if (ctx->aead == NULL) |
+ return; |
+ ctx->aead->cleanup(ctx); |
+ ctx->aead = NULL; |
} |
-int X509_set_subject_name(X509 *x, X509_NAME *name) |
+/* check_alias returns 0 if |out| points within the buffer determined by |in| |
+ * and |in_len| and 1 otherwise. |
+ * |
+ * When processing, there's only an issue if |out| points within in[:in_len] |
+ * and isn't equal to |in|. If that's the case then writing the output will |
+ * stomp input that hasn't been read yet. |
+ * |
+ * This function checks for that case. */ |
+static int check_alias(const unsigned char *in, size_t in_len, |
+ const unsigned char *out) |
{ |
- if ((x == NULL) || (x->cert_info == NULL)) return(0); |
- return(X509_NAME_set(&x->cert_info->subject,name)); |
+ if (out <= in) |
+ return 1; |
+ if (in + in_len <= out) |
+ return 1; |
+ return 0; |
} |
-int X509_set_notBefore(X509 *x, const ASN1_TIME *tm) |
+ssize_t EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, |
+ unsigned char *out, size_t max_out_len, |
+ const unsigned char *nonce, size_t nonce_len, |
+ const unsigned char *in, size_t in_len, |
+ const unsigned char *ad, size_t ad_len) |
{ |
- ASN1_TIME *in; |
+ size_t possible_out_len = in_len + ctx->aead->overhead; |
+ ssize_t r; |
- if ((x == NULL) || (x->cert_info->validity == NULL)) return(0); |
- in=x->cert_info->validity->notBefore; |
- if (in != tm) |
+ if (possible_out_len < in_len /* overflow */ || |
+ possible_out_len > SSIZE_MAX /* return value cannot be |
+ represented */) |
{ |
- in=M_ASN1_TIME_dup(tm); |
- if (in != NULL) |
- { |
- M_ASN1_TIME_free(x->cert_info->validity->notBefore); |
- x->cert_info->validity->notBefore=in; |
- } |
+ EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_TOO_LARGE); |
+ goto error; |
} |
- return(in != NULL); |
+ |
+ if (!check_alias(in, in_len, out)) |
+ { |
+ EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_OUTPUT_ALIASES_INPUT); |
+ goto error; |
+ } |
+ |
+ r = ctx->aead->seal(ctx, out, max_out_len, nonce, nonce_len, |
+ in, in_len, ad, ad_len); |
+ if (r >= 0) |
+ return r; |
+ |
+error: |
+ /* In the event of an error, clear the output buffer so that a caller |
+ * that doesn't check the return value doesn't send raw data. */ |
+ memset(out, 0, max_out_len); |
+ return -1; |
} |
-int X509_set_notAfter(X509 *x, const ASN1_TIME *tm) |
+ssize_t EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, |
+ unsigned char *out, size_t max_out_len, |
+ const unsigned char *nonce, size_t nonce_len, |
+ const unsigned char *in, size_t in_len, |
+ const unsigned char *ad, size_t ad_len) |
{ |
- ASN1_TIME *in; |
+ ssize_t r; |
- if ((x == NULL) || (x->cert_info->validity == NULL)) return(0); |
- in=x->cert_info->validity->notAfter; |
- if (in != tm) |
+ if (in_len > SSIZE_MAX) |
{ |
- in=M_ASN1_TIME_dup(tm); |
- if (in != NULL) |
- { |
- M_ASN1_TIME_free(x->cert_info->validity->notAfter); |
- x->cert_info->validity->notAfter=in; |
- } |
+ EVPerr(EVP_F_AEAD_CTX_OPEN, EVP_R_TOO_LARGE); |
+ goto error; /* may not be able to represent return value. */ |
} |
- return(in != NULL); |
- } |
-int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) |
- { |
- if ((x == NULL) || (x->cert_info == NULL)) return(0); |
- return(X509_PUBKEY_set(&(x->cert_info->key),pkey)); |
- } |
+ if (!check_alias(in, in_len, out)) |
+ { |
+ EVPerr(EVP_F_AEAD_CTX_OPEN, EVP_R_OUTPUT_ALIASES_INPUT); |
+ goto error; |
+ } |
+ r = ctx->aead->open(ctx, out, max_out_len, nonce, nonce_len, |
+ in, in_len, ad, ad_len); |
+ if (r >= 0) |
+ return r; |
+error: |
+ /* In the event of an error, clear the output buffer so that a caller |
+ * that doesn't check the return value doesn't try and process bad |
+ * data. */ |
+ memset(out, 0, max_out_len); |
+ return -1; |
+ } |