doc: Fix description of the field 11.
[gnupg.git] / sm / misc.c
1 /* misc.c - Miscellaneous functions
2  * Copyright (C) 2004, 2009, 2011 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <https://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <unistd.h>
27 #ifdef HAVE_LOCALE_H
28 #include <locale.h>
29 #endif
30
31 #include "gpgsm.h"
32 #include "../common/i18n.h"
33 #include "../common/sysutils.h"
34 #include "../common/tlv.h"
35 #include "../common/sexp-parse.h"
36
37
38 /* Setup the environment so that the pinentry is able to get all
39    required information.  This is used prior to an exec of the
40    protect-tool. */
41 void
42 setup_pinentry_env (void)
43 {
44 #ifndef HAVE_W32_SYSTEM
45   char *lc;
46   const char *name, *value;
47   int iterator;
48
49   /* Try to make sure that GPG_TTY has been set.  This is needed if we
50      call for example the protect-tools with redirected stdin and thus
51      it won't be able to ge a default by itself.  Try to do it here
52      but print a warning.  */
53   value = session_env_getenv (opt.session_env, "GPG_TTY");
54   if (value)
55     gnupg_setenv ("GPG_TTY", value, 1);
56   else if (!(lc=getenv ("GPG_TTY")) || !*lc)
57     {
58       log_error (_("GPG_TTY has not been set - "
59                    "using maybe bogus default\n"));
60       lc = gnupg_ttyname (0);
61       if (!lc)
62         lc = "/dev/tty";
63       gnupg_setenv ("GPG_TTY", lc, 1);
64     }
65
66   if (opt.lc_ctype)
67     gnupg_setenv ("LC_CTYPE", opt.lc_ctype, 1);
68 #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
69   else if ( (lc = setlocale (LC_CTYPE, "")) )
70     gnupg_setenv ("LC_CTYPE", lc, 1);
71 #endif
72
73   if (opt.lc_messages)
74     gnupg_setenv ("LC_MESSAGES", opt.lc_messages, 1);
75 #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
76   else if ( (lc = setlocale (LC_MESSAGES, "")) )
77     gnupg_setenv ("LC_MESSAGES", lc, 1);
78 #endif
79
80   iterator = 0;
81   while ((name = session_env_list_stdenvnames (&iterator, NULL)))
82     {
83       if (!strcmp (name, "GPG_TTY"))
84         continue;  /* Already set.  */
85       value = session_env_getenv (opt.session_env, name);
86       if (value)
87         gnupg_setenv (name, value, 1);
88     }
89
90 #endif /*!HAVE_W32_SYSTEM*/
91 }
92
93
94
95 /* Transform a sig-val style s-expression as returned by Libgcrypt to
96    one which includes an algorithm identifier encoding the public key
97    and the hash algorithm.  The public key algorithm is taken directly
98    from SIGVAL and the hash algorithm is given by MDALGO.  This is
99    required because X.509 merges the public key algorithm and the hash
100    algorithm into one OID but Libgcrypt is not aware of that.  The
101    function ignores missing parameters so that it can also be used to
102    create an siginfo value as expected by ksba_certreq_set_siginfo.
103    To create a siginfo s-expression a public-key s-expression may be
104    used instead of a sig-val.  We only support RSA for now.  */
105 gpg_error_t
106 transform_sigval (const unsigned char *sigval, size_t sigvallen, int mdalgo,
107                   unsigned char **r_newsigval, size_t *r_newsigvallen)
108 {
109   gpg_error_t err;
110   const unsigned char *buf, *tok;
111   size_t buflen, toklen;
112   int depth, last_depth1, last_depth2, pkalgo;
113   int is_pubkey = 0;
114   const unsigned char *rsa_s, *ecc_r, *ecc_s;
115   size_t rsa_s_len, ecc_r_len, ecc_s_len;
116   const char *oid;
117   gcry_sexp_t sexp;
118
119   rsa_s = ecc_r = ecc_s = NULL;
120   rsa_s_len = ecc_r_len = ecc_s_len = 0;
121
122   *r_newsigval = NULL;
123   if (r_newsigvallen)
124     *r_newsigvallen = 0;
125
126   buf = sigval;
127   buflen = sigvallen;
128   depth = 0;
129   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
130     return err;
131   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
132     return err;
133   if (tok && toklen == 7 && !memcmp ("sig-val", tok, toklen))
134     ;
135   else if (tok && toklen == 10 && !memcmp ("public-key", tok, toklen))
136     is_pubkey = 1;
137   else
138     return gpg_error (GPG_ERR_UNKNOWN_SEXP);
139   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
140     return err;
141   if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
142     return err;
143   if (!tok)
144     return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
145   if (toklen == 3 && !memcmp ("rsa", tok, 3))
146     pkalgo = GCRY_PK_RSA;
147   else if (toklen == 5 && !memcmp ("ecdsa", tok, 5))
148     pkalgo = GCRY_PK_ECC;
149   else if (toklen == 5 && !memcmp ("eddsa", tok, 5))
150     pkalgo = GCRY_PK_EDDSA;
151   else
152     return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
153
154   last_depth1 = depth;
155   while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
156          && depth && depth >= last_depth1)
157     {
158       if (tok)
159         return gpg_error (GPG_ERR_UNKNOWN_SEXP);
160       if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
161         return err;
162       if (tok && toklen == 1)
163         {
164           const unsigned char **mpi = NULL;
165           size_t *mpi_len = NULL;
166
167           switch (*tok)
168             {
169             case 's':
170               if (pkalgo == GCRY_PK_RSA)
171                 {
172                   mpi = &rsa_s;
173                   mpi_len = &rsa_s_len;
174                 }
175               else if (pkalgo == GCRY_PK_ECC || pkalgo == GCRY_PK_EDDSA)
176                 {
177                   mpi = &ecc_s;
178                   mpi_len = &ecc_s_len;
179                 }
180               break;
181
182             case 'r': mpi = &ecc_r; mpi_len = &ecc_r_len; break;
183             default:  mpi = NULL;   mpi_len = NULL; break;
184             }
185
186           if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
187             return err;
188           if (tok && mpi)
189             {
190               *mpi = tok;
191               *mpi_len = toklen;
192             }
193         }
194
195       /* Skip to the end of the list. */
196       last_depth2 = depth;
197       while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
198              && depth && depth >= last_depth2)
199         ;
200       if (err)
201         return err;
202     }
203   if (err)
204     return err;
205
206   /* Map the hash algorithm to an OID.  */
207   if (mdalgo < 0 || mdalgo > (1<<15) || pkalgo < 0 || pkalgo > (1<<15))
208     return gpg_error (GPG_ERR_DIGEST_ALGO);
209
210   switch (mdalgo | (pkalgo << 16))
211     {
212     case GCRY_MD_SHA1 | (GCRY_PK_RSA << 16):
213       oid = "1.2.840.113549.1.1.5";  /* sha1WithRSAEncryption */
214       break;
215
216     case GCRY_MD_SHA256 | (GCRY_PK_RSA << 16):
217       oid = "1.2.840.113549.1.1.11"; /* sha256WithRSAEncryption */
218       break;
219
220     case GCRY_MD_SHA384 | (GCRY_PK_RSA << 16):
221       oid = "1.2.840.113549.1.1.12"; /* sha384WithRSAEncryption */
222       break;
223
224     case GCRY_MD_SHA512 | (GCRY_PK_RSA << 16):
225       oid = "1.2.840.113549.1.1.13"; /* sha512WithRSAEncryption */
226       break;
227
228     case GCRY_MD_SHA224 | (GCRY_PK_ECC << 16):
229       oid = "1.2.840.10045.4.3.1"; /* ecdsa-with-sha224 */
230       break;
231
232     case GCRY_MD_SHA256 | (GCRY_PK_ECC << 16):
233       oid = "1.2.840.10045.4.3.2"; /* ecdsa-with-sha256 */
234       break;
235
236     case GCRY_MD_SHA384 | (GCRY_PK_ECC << 16):
237       oid = "1.2.840.10045.4.3.3"; /* ecdsa-with-sha384 */
238       break;
239
240     case GCRY_MD_SHA512 | (GCRY_PK_ECC << 16):
241       oid = "1.2.840.10045.4.3.4"; /* ecdsa-with-sha512 */
242       break;
243
244     case GCRY_MD_SHA512 | (GCRY_PK_EDDSA << 16):
245       oid = "1.3.101.112"; /* ed25519 */
246       break;
247
248     default:
249       return gpg_error (GPG_ERR_DIGEST_ALGO);
250     }
251
252   if (is_pubkey)
253     err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s))", oid);
254   else if (pkalgo == GCRY_PK_RSA)
255     err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(s%b)))", oid,
256                            (int)rsa_s_len, rsa_s);
257   else if (pkalgo == GCRY_PK_ECC || pkalgo == GCRY_PK_EDDSA)
258     err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(r%b)(s%b)))", oid,
259                            (int)ecc_r_len, ecc_r, (int)ecc_s_len, ecc_s);
260   if (err)
261     return err;
262   err = make_canon_sexp (sexp, r_newsigval, r_newsigvallen);
263   gcry_sexp_release (sexp);
264
265   return err;
266 }