xref: /freebsd/crypto/openssl/doc/man3/ASN1_item_sign.pod (revision aa7957345732816fb0ba8308798d2f79f45597f9)
1b077aed3SPierre Pronchery=pod
2b077aed3SPierre Pronchery
3b077aed3SPierre Pronchery=head1 NAME
4b077aed3SPierre Pronchery
5b077aed3SPierre ProncheryASN1_item_sign, ASN1_item_sign_ex, ASN1_item_sign_ctx,
6b077aed3SPierre ProncheryASN1_item_verify, ASN1_item_verify_ex, ASN1_item_verify_ctx -
7b077aed3SPierre ProncheryASN1 sign and verify
8b077aed3SPierre Pronchery
9b077aed3SPierre Pronchery=head1 SYNOPSIS
10b077aed3SPierre Pronchery
11b077aed3SPierre Pronchery #include <openssl/x509.h>
12b077aed3SPierre Pronchery
13b077aed3SPierre Pronchery int ASN1_item_sign_ex(const ASN1_ITEM *it, X509_ALGOR *algor1,
14b077aed3SPierre Pronchery                       X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
15b077aed3SPierre Pronchery                       const void *data, const ASN1_OCTET_STRING *id,
16b077aed3SPierre Pronchery                       EVP_PKEY *pkey, const EVP_MD *md, OSSL_LIB_CTX *libctx,
17b077aed3SPierre Pronchery                       const char *propq);
18b077aed3SPierre Pronchery
19b077aed3SPierre Pronchery int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
20b077aed3SPierre Pronchery                    ASN1_BIT_STRING *signature, const void *data,
21b077aed3SPierre Pronchery                    EVP_PKEY *pkey, const EVP_MD *md);
22b077aed3SPierre Pronchery
23b077aed3SPierre Pronchery int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
24b077aed3SPierre Pronchery                        X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
25b077aed3SPierre Pronchery                        const void *data, EVP_MD_CTX *ctx);
26b077aed3SPierre Pronchery
27b077aed3SPierre Pronchery int ASN1_item_verify_ex(const ASN1_ITEM *it, const X509_ALGOR *alg,
28b077aed3SPierre Pronchery                         const ASN1_BIT_STRING *signature, const void *data,
29b077aed3SPierre Pronchery                         const ASN1_OCTET_STRING *id, EVP_PKEY *pkey,
30b077aed3SPierre Pronchery                         OSSL_LIB_CTX *libctx, const char *propq);
31b077aed3SPierre Pronchery
32b077aed3SPierre Pronchery int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *alg,
33b077aed3SPierre Pronchery                      const ASN1_BIT_STRING *signature, const void *data,
34b077aed3SPierre Pronchery                      EVP_PKEY *pkey);
35b077aed3SPierre Pronchery
36b077aed3SPierre Pronchery int ASN1_item_verify_ctx(const ASN1_ITEM *it, const X509_ALGOR *alg,
37b077aed3SPierre Pronchery                          const ASN1_BIT_STRING *signature, const void *data,
38b077aed3SPierre Pronchery                          EVP_MD_CTX *ctx);
39b077aed3SPierre Pronchery
40b077aed3SPierre Pronchery=head1 DESCRIPTION
41b077aed3SPierre Pronchery
42b077aed3SPierre ProncheryASN1_item_sign_ex() is used to sign arbitrary ASN1 data using a data object
43b077aed3SPierre ProncheryI<data>, the ASN.1 structure I<it>, private key I<pkey> and message digest I<md>.
44b077aed3SPierre ProncheryThe data that is signed is formed by taking the data object in I<data> and
45b077aed3SPierre Proncheryconverting it to der format using the ASN.1 structure I<it>.
46b077aed3SPierre ProncheryThe I<data> that will be signed, and a structure containing the signature may
47b077aed3SPierre Proncheryboth have a copy of the B<X509_ALGOR>. The ASN1_item_sign_ex() function will
48b077aed3SPierre Proncherywrite the correct B<X509_ALGOR> to the structs based on the algorithms and
49b077aed3SPierre Proncheryparameters that have been set up. If one of I<algor1> or I<algor2> points to the
50b077aed3SPierre ProncheryB<X509_ALGOR> of the I<data> to be signed, then that B<X509_ALGOR> will first be
51b077aed3SPierre Proncherywritten before the signature is generated.
52b077aed3SPierre ProncheryExamples of valid values that can be used by the ASN.1 structure I<it> are
53b077aed3SPierre ProncheryASN1_ITEM_rptr(X509_CINF), ASN1_ITEM_rptr(X509_REQ_INFO) and
54b077aed3SPierre ProncheryASN1_ITEM_rptr(X509_CRL_INFO).
55b077aed3SPierre ProncheryThe B<OSSL_LIB_CTX> specified in I<libctx> and the property query string
56b077aed3SPierre Proncheryspecified in I<props> are used when searching for algorithms in providers.
57b077aed3SPierre ProncheryThe generated signature is set into I<signature>.
58b077aed3SPierre ProncheryThe optional parameter I<id> can be NULL, but can be set for special key types.
59b077aed3SPierre ProncherySee EVP_PKEY_CTX_set1_id() for further info. The output parameters <algor1> and
60b077aed3SPierre ProncheryI<algor2> are ignored if they are NULL.
61b077aed3SPierre Pronchery
62b077aed3SPierre ProncheryASN1_item_sign() is similar to ASN1_item_sign_ex() but uses default values of
63b077aed3SPierre ProncheryNULL for the I<id>, I<libctx> and I<propq>.
64b077aed3SPierre Pronchery
65*aa795734SPierre ProncheryASN1_item_sign_ctx() is similar to ASN1_item_sign() but uses the parameters
66b077aed3SPierre Proncherycontained in digest context I<ctx>.
67b077aed3SPierre Pronchery
68b077aed3SPierre ProncheryASN1_item_verify_ex() is used to verify the signature I<signature> of internal
69b077aed3SPierre Proncherydata I<data> using the public key I<pkey> and algorithm identifier I<alg>.
70b077aed3SPierre ProncheryThe data that is verified is formed by taking the data object in I<data> and
71b077aed3SPierre Proncheryconverting it to der format using the ASN.1 structure I<it>.
72b077aed3SPierre ProncheryThe B<OSSL_LIB_CTX> specified in I<libctx> and the property query string
73b077aed3SPierre Proncheryspecified in I<props> are used when searching for algorithms in providers.
74b077aed3SPierre ProncheryThe optional parameter I<id> can be NULL, but can be set for special key types.
75b077aed3SPierre ProncherySee EVP_PKEY_CTX_set1_id() for further info.
76b077aed3SPierre Pronchery
77b077aed3SPierre ProncheryASN1_item_verify() is similar to ASN1_item_verify_ex() but uses default values of
78b077aed3SPierre ProncheryNULL for the I<id>, I<libctx> and I<propq>.
79b077aed3SPierre Pronchery
80*aa795734SPierre ProncheryASN1_item_verify_ctx() is similar to ASN1_item_verify() but uses the parameters
81b077aed3SPierre Proncherycontained in digest context I<ctx>.
82b077aed3SPierre Pronchery
83b077aed3SPierre Pronchery
84b077aed3SPierre Pronchery=head1 RETURN VALUES
85b077aed3SPierre Pronchery
86b077aed3SPierre ProncheryAll sign functions return the size of the signature in bytes for success and
87b077aed3SPierre Proncheryzero for failure.
88b077aed3SPierre Pronchery
89b077aed3SPierre ProncheryAll verify functions return 1 if the signature is valid and 0 if the signature
90b077aed3SPierre Proncherycheck fails. If the signature could not be checked at all because it was
91b077aed3SPierre Proncheryill-formed or some other error occurred then -1 is returned.
92b077aed3SPierre Pronchery
93b077aed3SPierre Pronchery=head1 EXAMPLES
94b077aed3SPierre Pronchery
95b077aed3SPierre ProncheryIn the following example a 'MyObject' object is signed using the key contained
96b077aed3SPierre Proncheryin an EVP_MD_CTX. The signature is written to MyObject.signature. The object is
97b077aed3SPierre Proncherythen output in DER format and then loaded back in and verified.
98b077aed3SPierre Pronchery
99b077aed3SPierre Pronchery #include <openssl/x509.h>
100b077aed3SPierre Pronchery #include <openssl/asn1t.h>
101b077aed3SPierre Pronchery
102b077aed3SPierre Pronchery /* An object used to store the ASN1 data fields that will be signed */
103b077aed3SPierre Pronchery typedef struct MySignInfoObject_st
104b077aed3SPierre Pronchery {
105b077aed3SPierre Pronchery     ASN1_INTEGER *version;
106b077aed3SPierre Pronchery     X509_ALGOR sig_alg;
107b077aed3SPierre Pronchery } MySignInfoObject;
108b077aed3SPierre Pronchery
109b077aed3SPierre Pronchery DECLARE_ASN1_FUNCTIONS(MySignInfoObject)
110b077aed3SPierre Pronchery /*
111b077aed3SPierre Pronchery  * A higher level object containing the ASN1 fields, signature alg and
112b077aed3SPierre Pronchery  * output signature.
113b077aed3SPierre Pronchery  */
114b077aed3SPierre Pronchery typedef struct MyObject_st
115b077aed3SPierre Pronchery {
116b077aed3SPierre Pronchery     MySignInfoObject info;
117b077aed3SPierre Pronchery     X509_ALGOR sig_alg;
118b077aed3SPierre Pronchery     ASN1_BIT_STRING *signature;
119b077aed3SPierre Pronchery } MyObject;
120b077aed3SPierre Pronchery
121b077aed3SPierre Pronchery DECLARE_ASN1_FUNCTIONS(MyObject)
122b077aed3SPierre Pronchery
123b077aed3SPierre Pronchery /* The ASN1 definition of MySignInfoObject */
124b077aed3SPierre Pronchery ASN1_SEQUENCE_cb(MySignInfoObject, NULL) = {
125b077aed3SPierre Pronchery     ASN1_SIMPLE(MySignInfoObject, version, ASN1_INTEGER)
126b077aed3SPierre Pronchery     ASN1_EMBED(MySignInfoObject, sig_alg, X509_ALGOR),
127b077aed3SPierre Pronchery } ASN1_SEQUENCE_END_cb(MySignInfoObject, MySignInfoObject)
128b077aed3SPierre Pronchery
129b077aed3SPierre Pronchery /* new, free, d2i & i2d functions for MySignInfoObject */
130b077aed3SPierre Pronchery IMPLEMENT_ASN1_FUNCTIONS(MySignInfoObject)
131b077aed3SPierre Pronchery
132b077aed3SPierre Pronchery /* The ASN1 definition of MyObject */
133b077aed3SPierre Pronchery ASN1_SEQUENCE_cb(MyObject, NULL) = {
134b077aed3SPierre Pronchery     ASN1_EMBED(MyObject, info, MySignInfoObject),
135b077aed3SPierre Pronchery     ASN1_EMBED(MyObject, sig_alg, X509_ALGOR),
136b077aed3SPierre Pronchery     ASN1_SIMPLE(MyObject, signature, ASN1_BIT_STRING)
137b077aed3SPierre Pronchery } ASN1_SEQUENCE_END_cb(MyObject, MyObject)
138b077aed3SPierre Pronchery
139b077aed3SPierre Pronchery /* new, free, d2i & i2d functions for MyObject */
140b077aed3SPierre Pronchery IMPLEMENT_ASN1_FUNCTIONS(MyObject)
141b077aed3SPierre Pronchery
142b077aed3SPierre Pronchery int test_asn1_item_sign_verify(const char *mdname, EVP_PKEY *pkey, long version)
143b077aed3SPierre Pronchery {
144b077aed3SPierre Pronchery    int ret = 0;
145b077aed3SPierre Pronchery    unsigned char *obj_der = NULL;
146b077aed3SPierre Pronchery    const unsigned char *p = NULL;
147b077aed3SPierre Pronchery    MyObject *obj = NULL, *loaded_obj = NULL;
148b077aed3SPierre Pronchery    const ASN1_ITEM *it = ASN1_ITEM_rptr(MySignInfoObject);
149b077aed3SPierre Pronchery    EVP_MD_CTX *sctx = NULL, *vctx = NULL;
150b077aed3SPierre Pronchery    int len;
151b077aed3SPierre Pronchery
152b077aed3SPierre Pronchery    /* Create MyObject and set its version */
153b077aed3SPierre Pronchery    obj = MyObject_new();
154b077aed3SPierre Pronchery    if (obj == NULL)
155b077aed3SPierre Pronchery        goto err;
156b077aed3SPierre Pronchery    if (!ASN1_INTEGER_set(obj->info.version, version))
157b077aed3SPierre Pronchery        goto err;
158b077aed3SPierre Pronchery
159b077aed3SPierre Pronchery    /* Set the key and digest used for signing */
160b077aed3SPierre Pronchery    sctx = EVP_MD_CTX_new();
161b077aed3SPierre Pronchery    if (sctx == NULL
162b077aed3SPierre Pronchery        || !EVP_DigestSignInit_ex(sctx, NULL, mdname, NULL, NULL, pkey))
163b077aed3SPierre Pronchery        goto err;
164b077aed3SPierre Pronchery
165b077aed3SPierre Pronchery    /*
166b077aed3SPierre Pronchery     * it contains the mapping between ASN.1 data and an object MySignInfoObject
167b077aed3SPierre Pronchery     * obj->info is the 'MySignInfoObject' object that will be
168b077aed3SPierre Pronchery     *   converted into DER data and then signed.
169b077aed3SPierre Pronchery     * obj->signature will contain the output signature.
170b077aed3SPierre Pronchery     * obj->sig_alg is filled with the private key's signing algorithm id.
171b077aed3SPierre Pronchery     * obj->info.sig_alg is another copy of the signing algorithm id that sits
172b077aed3SPierre Pronchery     * within MyObject.
173b077aed3SPierre Pronchery     */
174b077aed3SPierre Pronchery    len = ASN1_item_sign_ctx(it, &obj->sig_alg, &obj->info.sig_alg,
175b077aed3SPierre Pronchery                             obj->signature, &obj->info, sctx);
176b077aed3SPierre Pronchery    if (len <= 0
177b077aed3SPierre Pronchery        || X509_ALGOR_cmp(&obj->sig_alg, &obj->info.sig_alg) != 0)
178b077aed3SPierre Pronchery        goto err;
179b077aed3SPierre Pronchery
180b077aed3SPierre Pronchery    /* Output MyObject in der form */
181b077aed3SPierre Pronchery    len = i2d_MyObject(obj, &obj_der);
182b077aed3SPierre Pronchery    if (len <= 0)
183b077aed3SPierre Pronchery        goto err;
184b077aed3SPierre Pronchery
185b077aed3SPierre Pronchery    /* Set the key and digest used for verifying */
186b077aed3SPierre Pronchery    vctx = EVP_MD_CTX_new();
187b077aed3SPierre Pronchery    if (vctx == NULL
188b077aed3SPierre Pronchery        || !EVP_DigestVerifyInit_ex(vctx, NULL, mdname, NULL, NULL, pkey))
189b077aed3SPierre Pronchery        goto err;
190b077aed3SPierre Pronchery
191b077aed3SPierre Pronchery    /* Load the der data back into an object */
192b077aed3SPierre Pronchery    p = obj_der;
193b077aed3SPierre Pronchery    loaded_obj = d2i_MyObject(NULL, &p, len);
194b077aed3SPierre Pronchery    if (loaded_obj == NULL)
195b077aed3SPierre Pronchery        goto err;
196b077aed3SPierre Pronchery    /* Verify the loaded object */
197b077aed3SPierre Pronchery    ret = ASN1_item_verify_ctx(it, &loaded_obj->sig_alg, loaded_obj->signature,
198b077aed3SPierre Pronchery                               &loaded_obj->info, vctx);
199b077aed3SPierre Proncheryerr:
200b077aed3SPierre Pronchery    OPENSSL_free(obj_der);
201b077aed3SPierre Pronchery    MyObject_free(loaded_obj);
202b077aed3SPierre Pronchery    MyObject_free(obj);
203b077aed3SPierre Pronchery    EVP_MD_CTX_free(sctx);
204b077aed3SPierre Pronchery    EVP_MD_CTX_free(vctx);
205b077aed3SPierre Pronchery    return ret;
206b077aed3SPierre Pronchery }
207b077aed3SPierre Pronchery
208b077aed3SPierre Pronchery=head1 SEE ALSO
209b077aed3SPierre Pronchery
210b077aed3SPierre ProncheryL<X509_sign(3)>,
211b077aed3SPierre ProncheryL<X509_verify(3)>
212b077aed3SPierre Pronchery
213b077aed3SPierre Pronchery=head1 HISTORY
214b077aed3SPierre Pronchery
215b077aed3SPierre ProncheryASN1_item_sign_ex() and ASN1_item_verify_ex() were added in OpenSSL 3.0.
216b077aed3SPierre Pronchery
217b077aed3SPierre Pronchery=head1 COPYRIGHT
218b077aed3SPierre Pronchery
219*aa795734SPierre ProncheryCopyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
220b077aed3SPierre Pronchery
221b077aed3SPierre ProncheryLicensed under the Apache License 2.0 (the "License").  You may not use
222b077aed3SPierre Proncherythis file except in compliance with the License.  You can obtain a copy
223b077aed3SPierre Proncheryin the file LICENSE in the source distribution or at
224b077aed3SPierre ProncheryL<https://www.openssl.org/source/license.html>.
225b077aed3SPierre Pronchery
226b077aed3SPierre Pronchery=cut
227