Line data Source code
1 : /* misc.c - Miscellaneous fucntions
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 "i18n.h"
33 : #include "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 0 : 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 0 : value = session_env_getenv (opt.session_env, "GPG_TTY");
54 0 : if (value)
55 0 : gnupg_setenv ("GPG_TTY", value, 1);
56 0 : else if (!(lc=getenv ("GPG_TTY")) || !*lc)
57 : {
58 0 : log_error (_("GPG_TTY has not been set - "
59 : "using maybe bogus default\n"));
60 0 : lc = gnupg_ttyname (0);
61 0 : if (!lc)
62 0 : lc = "/dev/tty";
63 0 : gnupg_setenv ("GPG_TTY", lc, 1);
64 : }
65 :
66 0 : if (opt.lc_ctype)
67 0 : gnupg_setenv ("LC_CTYPE", opt.lc_ctype, 1);
68 : #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE)
69 0 : else if ( (lc = setlocale (LC_CTYPE, "")) )
70 0 : gnupg_setenv ("LC_CTYPE", lc, 1);
71 : #endif
72 :
73 0 : if (opt.lc_messages)
74 0 : gnupg_setenv ("LC_MESSAGES", opt.lc_messages, 1);
75 : #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES)
76 0 : else if ( (lc = setlocale (LC_MESSAGES, "")) )
77 0 : gnupg_setenv ("LC_MESSAGES", lc, 1);
78 : #endif
79 :
80 0 : iterator = 0;
81 0 : while ((name = session_env_list_stdenvnames (&iterator, NULL)))
82 : {
83 0 : if (!strcmp (name, "GPG_TTY"))
84 0 : continue; /* Already set. */
85 0 : value = session_env_getenv (opt.session_env, name);
86 0 : if (value)
87 0 : gnupg_setenv (name, value, 1);
88 : }
89 :
90 : #endif /*!HAVE_W32_SYSTEM*/
91 0 : }
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 0 : 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;
113 0 : int is_pubkey = 0;
114 0 : const unsigned char *rsa_s = NULL;
115 0 : size_t rsa_s_len = 0;
116 : const char *oid;
117 : gcry_sexp_t sexp;
118 :
119 0 : *r_newsigval = NULL;
120 0 : if (r_newsigvallen)
121 0 : *r_newsigvallen = 0;
122 :
123 0 : buf = sigval;
124 0 : buflen = sigvallen;
125 0 : depth = 0;
126 0 : if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
127 0 : return err;
128 0 : if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
129 0 : return err;
130 0 : if (tok && toklen == 7 && !memcmp ("sig-val", tok, toklen))
131 : ;
132 0 : else if (tok && toklen == 10 && !memcmp ("public-key", tok, toklen))
133 0 : is_pubkey = 1;
134 : else
135 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
136 0 : if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
137 0 : return err;
138 0 : if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
139 0 : return err;
140 0 : if (!tok || toklen != 3 || memcmp ("rsa", tok, toklen))
141 0 : return gpg_error (GPG_ERR_WRONG_PUBKEY_ALGO);
142 :
143 0 : last_depth1 = depth;
144 0 : while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
145 0 : && depth && depth >= last_depth1)
146 : {
147 0 : if (tok)
148 0 : return gpg_error (GPG_ERR_UNKNOWN_SEXP);
149 0 : if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
150 0 : return err;
151 0 : if (tok && toklen == 1)
152 : {
153 : const unsigned char **mpi;
154 : size_t *mpi_len;
155 :
156 0 : switch (*tok)
157 : {
158 0 : case 's': mpi = &rsa_s; mpi_len = &rsa_s_len; break;
159 0 : default: mpi = NULL; mpi_len = NULL; break;
160 : }
161 0 : if (mpi && *mpi)
162 0 : return gpg_error (GPG_ERR_DUP_VALUE);
163 :
164 0 : if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen)))
165 0 : return err;
166 0 : if (tok && mpi)
167 : {
168 0 : *mpi = tok;
169 0 : *mpi_len = toklen;
170 : }
171 : }
172 :
173 : /* Skip to the end of the list. */
174 0 : last_depth2 = depth;
175 0 : while (!(err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))
176 0 : && depth && depth >= last_depth2)
177 : ;
178 0 : if (err)
179 0 : return err;
180 : }
181 0 : if (err)
182 0 : return err;
183 :
184 : /* Map the hash algorithm to an OID. */
185 0 : switch (mdalgo)
186 : {
187 : case GCRY_MD_SHA1:
188 0 : oid = "1.2.840.113549.1.1.5"; /* sha1WithRSAEncryption */
189 0 : break;
190 :
191 : case GCRY_MD_SHA256:
192 0 : oid = "1.2.840.113549.1.1.11"; /* sha256WithRSAEncryption */
193 0 : break;
194 :
195 : case GCRY_MD_SHA384:
196 0 : oid = "1.2.840.113549.1.1.12"; /* sha384WithRSAEncryption */
197 0 : break;
198 :
199 : case GCRY_MD_SHA512:
200 0 : oid = "1.2.840.113549.1.1.13"; /* sha512WithRSAEncryption */
201 0 : break;
202 :
203 : default:
204 0 : return gpg_error (GPG_ERR_DIGEST_ALGO);
205 : }
206 :
207 0 : if (rsa_s && !is_pubkey)
208 0 : err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s(s%b)))",
209 : oid, (int)rsa_s_len, rsa_s);
210 : else
211 0 : err = gcry_sexp_build (&sexp, NULL, "(sig-val(%s))", oid);
212 0 : if (err)
213 0 : return err;
214 0 : err = make_canon_sexp (sexp, r_newsigval, r_newsigvallen);
215 0 : gcry_sexp_release (sexp);
216 :
217 0 : return err;
218 : }
|