Mirror of BoringSSL (grpc依赖) https://boringssl.googlesource.com/boringssl
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
5.0 KiB

/*
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
* 2000.
*/
/* ====================================================================
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/digest.h>
#include <openssl/obj.h>
ASN1_SEQUENCE(X509_ALGOR) = {
ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
} ASN1_SEQUENCE_END(X509_ALGOR)
ASN1_ITEM_TEMPLATE(X509_ALGORS) =
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
ASN1_ITEM_TEMPLATE_END(X509_ALGORS)
IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR)
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR)
IMPLEMENT_ASN1_SET_OF(X509_ALGOR)
Align with OpenSSL on constness of static ASN1_OBJECTs. ASN1_OBJECTs are awkward. Sometimes they are static, when returned from OBJ_nid2obj, and sometimes they are dynamic, when parsed from crypto/asn1. Most structures in crypto/asn1 need to support unknown OIDs and thus must own their ASN1_OBJECTs. But they also may be initialized with static ones in various APIs, such as X509_ALGOR_set0. To make that work, ASN1_OBJECT_free detects static ASN1_OBJECTs and is a no-op. Functions like X509_ALGOR_set0 take ownership, so OpenSSL has them take a non-const ASN1_OBJECT*. To match, OBJ_nid2obj then returns a non-const ASN1_OBJECT*, to signal that it is freeable. However, this means OBJ_nid2obj's mutability doesn't match its return type. In the fork, we switched OBJ_nid2obj to return const. But, in doing so, we had to make X509_ALGOR_set0 and X509_PUBKEY_set0_param take const ASN1_OBJECT, even though they would actually take ownership of dynamic ASN1_OBJECTs. There are also a few internal casts with a TODO to be const-correct. Neither situation is ideal. (Perhaps a more sound model would be to copy static ASN1_OBJECTs before putting them in most structs. But that would not match current usage.) But I think aligning with OpenSSL is the lesser evil here, since it avoids misleading set0 functions. Managing ownership of ASN1_OBJECTs is much more common than mutating them. To that end, I've added a note that ASN1_OBJECTs you didn't create must be assumed immutable[*]. Update-Note: The change to OBJ_nid2obj should be compatible. The changes to X509_PUBKEY_set0_param and X509_ALGOR_set0 may require fixing some pointer types. [*] This is *almost* honored by all of our functions. The exception is c2i_ASN1_OBJECT, which instead checks the DYNAMIC flag as part of the object reuse business. This would come up if we ever embedded ASN1_OBJECTs directly in structs. Change-Id: I1e6c700645c12b43323dd3887adb74e795c285b9 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/46164 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Adam Langley <agl@google.com> Reviewed-by: Adam Langley <agl@google.com>
4 years ago
int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
{
if (!alg)
return 0;
if (ptype != V_ASN1_UNDEF) {
if (alg->parameter == NULL)
alg->parameter = ASN1_TYPE_new();
if (alg->parameter == NULL)
return 0;
}
if (alg) {
Align with OpenSSL on constness of static ASN1_OBJECTs. ASN1_OBJECTs are awkward. Sometimes they are static, when returned from OBJ_nid2obj, and sometimes they are dynamic, when parsed from crypto/asn1. Most structures in crypto/asn1 need to support unknown OIDs and thus must own their ASN1_OBJECTs. But they also may be initialized with static ones in various APIs, such as X509_ALGOR_set0. To make that work, ASN1_OBJECT_free detects static ASN1_OBJECTs and is a no-op. Functions like X509_ALGOR_set0 take ownership, so OpenSSL has them take a non-const ASN1_OBJECT*. To match, OBJ_nid2obj then returns a non-const ASN1_OBJECT*, to signal that it is freeable. However, this means OBJ_nid2obj's mutability doesn't match its return type. In the fork, we switched OBJ_nid2obj to return const. But, in doing so, we had to make X509_ALGOR_set0 and X509_PUBKEY_set0_param take const ASN1_OBJECT, even though they would actually take ownership of dynamic ASN1_OBJECTs. There are also a few internal casts with a TODO to be const-correct. Neither situation is ideal. (Perhaps a more sound model would be to copy static ASN1_OBJECTs before putting them in most structs. But that would not match current usage.) But I think aligning with OpenSSL is the lesser evil here, since it avoids misleading set0 functions. Managing ownership of ASN1_OBJECTs is much more common than mutating them. To that end, I've added a note that ASN1_OBJECTs you didn't create must be assumed immutable[*]. Update-Note: The change to OBJ_nid2obj should be compatible. The changes to X509_PUBKEY_set0_param and X509_ALGOR_set0 may require fixing some pointer types. [*] This is *almost* honored by all of our functions. The exception is c2i_ASN1_OBJECT, which instead checks the DYNAMIC flag as part of the object reuse business. This would come up if we ever embedded ASN1_OBJECTs directly in structs. Change-Id: I1e6c700645c12b43323dd3887adb74e795c285b9 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/46164 Commit-Queue: David Benjamin <davidben@google.com> Commit-Queue: Adam Langley <agl@google.com> Reviewed-by: Adam Langley <agl@google.com>
4 years ago
ASN1_OBJECT_free(alg->algorithm);
alg->algorithm = aobj;
}
if (ptype == 0)
return 1;
if (ptype == V_ASN1_UNDEF) {
if (alg->parameter) {
ASN1_TYPE_free(alg->parameter);
alg->parameter = NULL;
}
} else
ASN1_TYPE_set(alg->parameter, ptype, pval);
return 1;
}
void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, const void **ppval,
const X509_ALGOR *algor)
{
if (paobj)
*paobj = algor->algorithm;
if (pptype) {
if (algor->parameter == NULL) {
*pptype = V_ASN1_UNDEF;
return;
} else
*pptype = algor->parameter->type;
if (ppval)
*ppval = algor->parameter->value.ptr;
}
}
/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
{
int param_type;
if (EVP_MD_flags(md) & EVP_MD_FLAG_DIGALGID_ABSENT)
param_type = V_ASN1_UNDEF;
else
param_type = V_ASN1_NULL;
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
}
/*
* X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise.
*/
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
{
int rv;
rv = OBJ_cmp(a->algorithm, b->algorithm);
if (rv)
return rv;
if (!a->parameter && !b->parameter)
return 0;
return ASN1_TYPE_cmp(a->parameter, b->parameter);
}