]>
Commit | Line | Data |
---|---|---|
7524b7b7 RL |
1 | /* |
2 | * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. | |
3 | * | |
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use | |
5 | * this file except in compliance with the License. You can obtain a copy | |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8 | */ | |
9 | ||
10 | #include <openssl/err.h> | |
11 | #include <openssl/ui.h> | |
12 | #include <openssl/core_names.h> | |
13 | #include "internal/cryptlib.h" | |
ece9304c | 14 | #include "encoder_local.h" |
7524b7b7 RL |
15 | |
16 | /* Passphrase callbacks for any who need it */ | |
17 | ||
18 | /* | |
19 | * First, define the generic passphrase function that supports both | |
20 | * outgoing (with passphrase verify) and incoming (without passphrase | |
21 | * verify) passphrase reading. | |
22 | */ | |
23 | static int do_passphrase(char *pass, size_t pass_size, size_t *pass_len, | |
24 | const OSSL_PARAM params[], void *arg, int verify, | |
25 | const UI_METHOD *ui_method, void *ui_data, int errlib) | |
26 | { | |
27 | const OSSL_PARAM *p; | |
28 | const char *prompt_info = NULL; | |
29 | char *prompt = NULL, *vpass = NULL; | |
30 | int prompt_idx = -1, verify_idx = -1; | |
31 | UI *ui = NULL; | |
32 | int ret = 0; | |
33 | ||
34 | if (!ossl_assert(pass != NULL && pass_size != 0 && pass_len != NULL)) { | |
35 | ERR_raise(errlib, ERR_R_PASSED_NULL_PARAMETER); | |
36 | return 0; | |
37 | } | |
38 | ||
39 | if ((p = OSSL_PARAM_locate_const(params, | |
40 | OSSL_PASSPHRASE_PARAM_INFO)) != NULL) { | |
41 | if (p->data_type != OSSL_PARAM_UTF8_STRING) | |
42 | return 0; | |
43 | prompt_info = p->data; | |
44 | } | |
45 | ||
46 | if ((ui = UI_new()) == NULL) { | |
47 | ERR_raise(errlib, ERR_R_MALLOC_FAILURE); | |
48 | return 0; | |
49 | } | |
50 | ||
4701f0a9 RL |
51 | if (ui_method != NULL) { |
52 | UI_set_method(ui, ui_method); | |
53 | if (ui_data != NULL) | |
54 | UI_add_user_data(ui, ui_data); | |
55 | } | |
7524b7b7 RL |
56 | |
57 | /* Get an application constructed prompt */ | |
58 | prompt = UI_construct_prompt(ui, "pass phrase", prompt_info); | |
ece9304c | 59 | if (prompt == NULL) { |
7524b7b7 RL |
60 | ERR_raise(errlib, ERR_R_MALLOC_FAILURE); |
61 | goto end; | |
62 | } | |
63 | ||
64 | prompt_idx = UI_add_input_string(ui, prompt, | |
65 | UI_INPUT_FLAG_DEFAULT_PWD, | |
66 | pass, 0, pass_size - 1) - 1; | |
67 | if (prompt_idx < 0) { | |
68 | ERR_raise(errlib, ERR_R_UI_LIB); | |
69 | goto end; | |
70 | } | |
71 | ||
72 | if (verify) { | |
73 | /* Get a buffer for verification prompt */ | |
74 | vpass = OPENSSL_zalloc(pass_size); | |
75 | if (vpass == NULL) { | |
76 | ERR_raise(errlib, ERR_R_MALLOC_FAILURE); | |
77 | goto end; | |
78 | } | |
79 | verify_idx = UI_add_verify_string(ui, prompt, | |
80 | UI_INPUT_FLAG_DEFAULT_PWD, | |
81 | vpass, 0, pass_size - 1, | |
82 | pass) - 1; | |
83 | if (verify_idx < 0) { | |
84 | ERR_raise(errlib, ERR_R_UI_LIB); | |
85 | goto end; | |
86 | } | |
87 | } | |
88 | ||
89 | switch (UI_process(ui)) { | |
90 | case -2: | |
91 | ERR_raise(errlib, ERR_R_INTERRUPTED_OR_CANCELLED); | |
92 | break; | |
93 | case -1: | |
94 | ERR_raise(errlib, ERR_R_UI_LIB); | |
95 | break; | |
96 | default: | |
97 | *pass_len = (size_t)UI_get_result_length(ui, prompt_idx); | |
98 | ret = 1; | |
99 | break; | |
100 | } | |
101 | ||
102 | end: | |
103 | OPENSSL_free(vpass); | |
104 | OPENSSL_free(prompt); | |
105 | UI_free(ui); | |
106 | return ret; | |
107 | } | |
108 | ||
109 | /* | |
ece9304c RL |
110 | * Encoders typically want to get an outgoing passphrase, while |
111 | * decoders typically want to get en incoming passphrase. | |
7524b7b7 | 112 | */ |
ece9304c RL |
113 | int ossl_encoder_passphrase_out_cb(char *pass, size_t pass_size, |
114 | size_t *pass_len, | |
115 | const OSSL_PARAM params[], void *arg) | |
7524b7b7 | 116 | { |
ece9304c | 117 | OSSL_ENCODER_CTX *ctx = arg; |
7524b7b7 RL |
118 | |
119 | if (!ossl_assert(ctx != NULL)) { | |
ece9304c | 120 | ERR_raise(ERR_LIB_OSSL_ENCODER, ERR_R_PASSED_NULL_PARAMETER); |
7524b7b7 RL |
121 | return 0; |
122 | } | |
123 | ||
124 | return do_passphrase(pass, pass_size, pass_len, params, arg, 1, | |
125 | ctx->ui_method, ctx->ui_data, | |
ece9304c | 126 | ERR_LIB_OSSL_ENCODER); |
7524b7b7 RL |
127 | } |
128 | ||
ece9304c RL |
129 | int ossl_decoder_passphrase_in_cb(char *pass, size_t pass_size, |
130 | size_t *pass_len, | |
131 | const OSSL_PARAM params[], void *arg) | |
7524b7b7 | 132 | { |
ece9304c | 133 | OSSL_DECODER_CTX *ctx = arg; |
7524b7b7 RL |
134 | |
135 | if (!ossl_assert(ctx != NULL)) { | |
ece9304c | 136 | ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); |
7524b7b7 RL |
137 | return 0; |
138 | } | |
139 | ||
140 | if (ctx->cached_passphrase != NULL) { | |
141 | size_t len = ctx->cached_passphrase_len; | |
142 | ||
143 | if (len > pass_size) | |
144 | len = pass_size; | |
145 | memcpy(pass, ctx->cached_passphrase, len); | |
146 | *pass_len = len; | |
147 | return 1; | |
148 | } else { | |
149 | if ((ctx->cached_passphrase = OPENSSL_zalloc(pass_size)) == NULL) { | |
ece9304c | 150 | ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); |
7524b7b7 RL |
151 | return 0; |
152 | } | |
153 | } | |
154 | if (do_passphrase(pass, pass_size, pass_len, params, arg, 0, | |
155 | ctx->ui_method, ctx->ui_data, | |
ece9304c | 156 | ERR_LIB_OSSL_DECODER)) { |
7524b7b7 RL |
157 | memcpy(ctx->cached_passphrase, pass, *pass_len); |
158 | ctx->cached_passphrase_len = *pass_len; | |
159 | return 1; | |
160 | } | |
161 | return 0; | |
162 | } |