xref: /openbmc/qemu/util/base64.c (revision 683685e7)
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