mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-17 10:04:41 +00:00
System: Trust: Certificates - work in progress for https://github.com/opnsense/core/issues/7248
* add download file dialog (key,cert or p12)
This commit is contained in:
parent
f25adff8fa
commit
e2e365df4b
@ -231,4 +231,43 @@ class CertController extends ApiMutableModelControllerBase
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate file download content
|
||||
* @param string $uuid certificate reference
|
||||
* @param string $type one of crt/prv/pkcs12,
|
||||
* $_POST['password'] my contain an optional password for the pkcs12 format
|
||||
* @return array
|
||||
*/
|
||||
public function generateFileAction($uuid=null, $type='crt')
|
||||
{
|
||||
$result = ['status' => 'failed'];
|
||||
if ($this->request->isPost() && !empty($uuid)) {
|
||||
$node = $this->getModel()->getNodeByReference('cert.'. $uuid);
|
||||
if ($node === null || empty((string)$node->crt_payload)) {
|
||||
$result['error'] = gettext('Misssing certificate');
|
||||
} elseif ($type == 'crt') {
|
||||
$result['status'] = 'ok';
|
||||
$result['payload'] = (string)$node->crt_payload;
|
||||
} elseif ($type == 'prv') {
|
||||
$result['status'] = 'ok';
|
||||
$result['payload'] = (string)$node->prv_payload;
|
||||
} elseif ($type == 'pkcs12') {
|
||||
$passphrase = $this->request->getPost('password', null, '');
|
||||
$tmp = CertStore::getPKCS12(
|
||||
(string)$node->crt_payload,
|
||||
(string)$node->prv_payload,
|
||||
(string)$node->descr,
|
||||
$passphrase
|
||||
);
|
||||
if (!empty($tmp['payload'])) {
|
||||
// binary data, we need to encode it to deliver it to the client
|
||||
$result['payload_b64'] = base64_encode($tmp['payload']);
|
||||
} else {
|
||||
$result['error'] = $tmp['error'] ?? '';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@ -485,6 +485,28 @@ class Store
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $certificate
|
||||
* @param string $private_key
|
||||
* @param string $friendly_name
|
||||
* @param string $passphrase
|
||||
* @return string
|
||||
*/
|
||||
public static function getPKCS12($certificate, $private_key, $friendly_name=null, $passphrase=null)
|
||||
{
|
||||
$old_err_level = error_reporting(0); /* prevent openssl error from going to stderr/stdout */
|
||||
$options = [];
|
||||
if (!empty($friendly_name)) {
|
||||
$options['friendly_name'] = $friendly_name;
|
||||
}
|
||||
$result = [];
|
||||
if (!openssl_pkcs12_export($certificate, $result['payload'], $private_key, $passphrase, $options)) {
|
||||
self::_addSSLErrors($result);
|
||||
}
|
||||
error_reporting($old_err_level);
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $cert certificate
|
||||
* @return array [stdout|stderr]
|
||||
|
||||
@ -74,6 +74,72 @@
|
||||
classname: 'fa fa-fw fa-info-circle',
|
||||
title: "{{ lang._('show certificate info') }}",
|
||||
sequence: 10
|
||||
},
|
||||
download: {
|
||||
method: function(event){
|
||||
let uuid = $(this).data("row-id") !== undefined ? $(this).data("row-id") : '';
|
||||
let $container = $("<div style='height:150px;'/>");
|
||||
let $type = $("<select id='download_type'/>");
|
||||
let $password = $("<input id='download_password' type='password'/>");
|
||||
$type.append($("<option value='crt'/>").text('Certificate'));
|
||||
$type.append($("<option value='prv'/>").text('Private key'));
|
||||
$type.append($("<option value='pkcs12' selected=selected/>").text('PKCS #12'));
|
||||
$container.append(
|
||||
$("<div class='form-group'/>").append(
|
||||
$("<label for='download_type'>{{ lang._('File type') }}</label>"),
|
||||
$type
|
||||
)
|
||||
);
|
||||
$container.append(
|
||||
$("<div class='form-group'/>").append(
|
||||
$("<label for='download_password'>{{ lang._('Password') }}</label>"),
|
||||
$password)
|
||||
);
|
||||
$type.change(function(){
|
||||
if ($(this).val() != 'pkcs12') {
|
||||
$password.closest('div').hide();
|
||||
} else {
|
||||
$password.closest('div').show();
|
||||
}
|
||||
});
|
||||
BootstrapDialog.show({
|
||||
title: "{{ lang._('Certificate download') }}",
|
||||
type:BootstrapDialog.TYPE_INFO,
|
||||
message: $container,
|
||||
buttons: [{
|
||||
label: "{{ lang._('Download') }}",
|
||||
action: function(dialogItself){
|
||||
let params = {};
|
||||
if ($password.val()) {
|
||||
params['password'] = $password.val();
|
||||
}
|
||||
ajaxCall(
|
||||
'/api/trust/cert/generate_file/'+uuid+'/'+$type.val(),
|
||||
params,
|
||||
function(data, status) {
|
||||
let payload = null;
|
||||
let filename = null;
|
||||
if (data.payload_b64) {
|
||||
payload = atob(data.payload_b64);
|
||||
filename = 'cert.p12';
|
||||
} else if (data.payload) {
|
||||
payload = data.payload;
|
||||
filename = $type.val() + '.pem';
|
||||
}
|
||||
if (payload !== null) {
|
||||
download_content(payload, filename, 'application/octet-stream');
|
||||
}
|
||||
}
|
||||
)
|
||||
dialogItself.close();
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
},
|
||||
classname: 'fa fa-fw fa-cloud-download',
|
||||
title: "{{ lang._('Download') }}",
|
||||
sequence: 10
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -210,7 +276,7 @@
|
||||
<th data-column-id="name" data-type="string">{{ lang._('Name') }}</th>
|
||||
<th data-column-id="valid_from" data-width="10em" data-type="datetime">{{ lang._('Valid from') }}</th>
|
||||
<th data-column-id="valid_to" data-width="10em" data-type="datetime">{{ lang._('Valid to') }}</th>
|
||||
<th data-column-id="commands" data-width="9em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
<th data-column-id="commands" data-width="11em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user