189bc0b6cSDaniel P. Berrange /*
289bc0b6cSDaniel P. Berrange * QEMU base64 helpers
389bc0b6cSDaniel P. Berrange *
489bc0b6cSDaniel P. Berrange * Copyright (c) 2015 Red Hat, Inc.
589bc0b6cSDaniel P. Berrange *
689bc0b6cSDaniel P. Berrange * This library is free software; you can redistribute it and/or
789bc0b6cSDaniel P. Berrange * modify it under the terms of the GNU Lesser General Public
889bc0b6cSDaniel P. Berrange * License as published by the Free Software Foundation; either
9*61f3c91aSChetan Pant * version 2.1 of the License, or (at your option) any later version.
1089bc0b6cSDaniel P. Berrange *
1189bc0b6cSDaniel P. Berrange * This library is distributed in the hope that it will be useful,
1289bc0b6cSDaniel P. Berrange * but WITHOUT ANY WARRANTY; without even the implied warranty of
1389bc0b6cSDaniel P. Berrange * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1489bc0b6cSDaniel P. Berrange * Lesser General Public License for more details.
1589bc0b6cSDaniel P. Berrange *
1689bc0b6cSDaniel P. Berrange * You should have received a copy of the GNU Lesser General Public
1789bc0b6cSDaniel P. Berrange * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1889bc0b6cSDaniel P. Berrange *
1989bc0b6cSDaniel P. Berrange */
2089bc0b6cSDaniel P. Berrange
21aafd7584SPeter Maydell #include "qemu/osdep.h"
22da34e65cSMarkus Armbruster #include "qapi/error.h"
2389bc0b6cSDaniel P. Berrange #include "qemu/base64.h"
2489bc0b6cSDaniel P. Berrange
2589bc0b6cSDaniel P. Berrange static const char *base64_valid_chars =
2689bc0b6cSDaniel P. Berrange "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n";
2789bc0b6cSDaniel P. Berrange
qbase64_decode(const char * input,size_t in_len,size_t * out_len,Error ** errp)2889bc0b6cSDaniel P. Berrange uint8_t *qbase64_decode(const char *input,
2989bc0b6cSDaniel P. Berrange size_t in_len,
3089bc0b6cSDaniel P. Berrange size_t *out_len,
3189bc0b6cSDaniel P. Berrange Error **errp)
3289bc0b6cSDaniel P. Berrange {
3389bc0b6cSDaniel P. Berrange *out_len = 0;
3489bc0b6cSDaniel P. Berrange
3589bc0b6cSDaniel P. Berrange if (in_len != -1) {
3689bc0b6cSDaniel P. Berrange /* Lack of NUL terminator is an error */
3789bc0b6cSDaniel P. Berrange if (input[in_len] != '\0') {
3889bc0b6cSDaniel P. Berrange error_setg(errp, "Base64 data is not NUL terminated");
3989bc0b6cSDaniel P. Berrange return NULL;
4089bc0b6cSDaniel P. Berrange }
4189bc0b6cSDaniel P. Berrange /* Check there's no NULs embedded since we expect
4289bc0b6cSDaniel P. Berrange * this to be valid base64 data */
4389bc0b6cSDaniel P. Berrange if (memchr(input, '\0', in_len) != NULL) {
4489bc0b6cSDaniel P. Berrange error_setg(errp, "Base64 data contains embedded NUL characters");
4589bc0b6cSDaniel P. Berrange return NULL;
4689bc0b6cSDaniel P. Berrange }
4789bc0b6cSDaniel P. Berrange
4889bc0b6cSDaniel P. Berrange /* Now we know its a valid nul terminated string
4989bc0b6cSDaniel P. Berrange * strspn is safe to use... */
5089bc0b6cSDaniel P. Berrange } else {
5189bc0b6cSDaniel P. Berrange in_len = strlen(input);
5289bc0b6cSDaniel P. Berrange }
5389bc0b6cSDaniel P. Berrange
5489bc0b6cSDaniel P. Berrange if (strspn(input, base64_valid_chars) != in_len) {
5589bc0b6cSDaniel P. Berrange error_setg(errp, "Base64 data contains invalid characters");
5689bc0b6cSDaniel P. Berrange return NULL;
5789bc0b6cSDaniel P. Berrange }
5889bc0b6cSDaniel P. Berrange
5989bc0b6cSDaniel P. Berrange return g_base64_decode(input, out_len);
6089bc0b6cSDaniel P. Berrange }
61