2 * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
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
10 #include <openssl/err.h>
11 #include <openssl/ui.h>
12 #include <openssl/core_names.h>
13 #include "internal/cryptlib.h"
14 #include "serializer_local.h"
16 /* Passphrase callbacks for any who need it */
19 * First, define the generic passphrase function that supports both
20 * outgoing (with passphrase verify) and incoming (without passphrase
21 * verify) passphrase reading.
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
)
28 const char *prompt_info
= NULL
;
29 char *prompt
= NULL
, *vpass
= NULL
;
30 int prompt_idx
= -1, verify_idx
= -1;
34 if (!ossl_assert(pass
!= NULL
&& pass_size
!= 0 && pass_len
!= NULL
)) {
35 ERR_raise(errlib
, ERR_R_PASSED_NULL_PARAMETER
);
39 if ((p
= OSSL_PARAM_locate_const(params
,
40 OSSL_PASSPHRASE_PARAM_INFO
)) != NULL
) {
41 if (p
->data_type
!= OSSL_PARAM_UTF8_STRING
)
43 prompt_info
= p
->data
;
46 if ((ui
= UI_new()) == NULL
) {
47 ERR_raise(errlib
, ERR_R_MALLOC_FAILURE
);
51 if (ui_method
!= NULL
) {
52 UI_set_method(ui
, ui_method
);
54 UI_add_user_data(ui
, ui_data
);
57 /* Get an application constructed prompt */
58 prompt
= UI_construct_prompt(ui
, "pass phrase", prompt_info
);
60 ERR_raise(errlib
, ERR_R_MALLOC_FAILURE
);
64 prompt_idx
= UI_add_input_string(ui
, prompt
,
65 UI_INPUT_FLAG_DEFAULT_PWD
,
66 pass
, 0, pass_size
- 1) - 1;
68 ERR_raise(errlib
, ERR_R_UI_LIB
);
73 /* Get a buffer for verification prompt */
74 vpass
= OPENSSL_zalloc(pass_size
);
76 ERR_raise(errlib
, ERR_R_MALLOC_FAILURE
);
79 verify_idx
= UI_add_verify_string(ui
, prompt
,
80 UI_INPUT_FLAG_DEFAULT_PWD
,
81 vpass
, 0, pass_size
- 1,
84 ERR_raise(errlib
, ERR_R_UI_LIB
);
89 switch (UI_process(ui
)) {
91 ERR_raise(errlib
, ERR_R_INTERRUPTED_OR_CANCELLED
);
94 ERR_raise(errlib
, ERR_R_UI_LIB
);
97 *pass_len
= (size_t)UI_get_result_length(ui
, prompt_idx
);
104 OPENSSL_free(prompt
);
110 * Serializers typically want to get an outgoing passphrase, while
111 * deserializers typically want to get en incoming passphrase.
113 int ossl_serializer_passphrase_out_cb(char *pass
, size_t pass_size
,
115 const OSSL_PARAM params
[], void *arg
)
117 OSSL_SERIALIZER_CTX
*ctx
= arg
;
119 if (!ossl_assert(ctx
!= NULL
)) {
120 ERR_raise(ERR_LIB_OSSL_SERIALIZER
, ERR_R_PASSED_NULL_PARAMETER
);
124 return do_passphrase(pass
, pass_size
, pass_len
, params
, arg
, 1,
125 ctx
->ui_method
, ctx
->ui_data
,
126 ERR_LIB_OSSL_SERIALIZER
);
129 int ossl_deserializer_passphrase_in_cb(char *pass
, size_t pass_size
,
131 const OSSL_PARAM params
[], void *arg
)
133 OSSL_DESERIALIZER_CTX
*ctx
= arg
;
135 if (!ossl_assert(ctx
!= NULL
)) {
136 ERR_raise(ERR_LIB_OSSL_DESERIALIZER
, ERR_R_PASSED_NULL_PARAMETER
);
140 if (ctx
->cached_passphrase
!= NULL
) {
141 size_t len
= ctx
->cached_passphrase_len
;
145 memcpy(pass
, ctx
->cached_passphrase
, len
);
149 if ((ctx
->cached_passphrase
= OPENSSL_zalloc(pass_size
)) == NULL
) {
150 ERR_raise(ERR_LIB_OSSL_DESERIALIZER
, ERR_R_MALLOC_FAILURE
);
154 if (do_passphrase(pass
, pass_size
, pass_len
, params
, arg
, 0,
155 ctx
->ui_method
, ctx
->ui_data
,
156 ERR_LIB_OSSL_DESERIALIZER
)) {
157 memcpy(ctx
->cached_passphrase
, pass
, *pass_len
);
158 ctx
->cached_passphrase_len
= *pass_len
;