1/* $NetBSD: lbase64.c,v 1.2 2021/08/14 16:14:56 christos Exp $ */ 2 3/* lbase64.c - routines for dealing with base64 strings */ 4/* $OpenLDAP$ */ 5/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 * 7 * Copyright 1998-2021 The OpenLDAP Foundation. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted only as authorized by the OpenLDAP 12 * Public License. 13 * 14 * A copy of this license is available in the file LICENSE in the 15 * top-level directory of the distribution or, alternatively, at 16 * <http://www.OpenLDAP.org/license.html>. 17 */ 18/* Portions Copyright (c) 1992-1996 Regents of the University of Michigan. 19 * All rights reserved. 20 * 21 * Redistribution and use in source and binary forms are permitted 22 * provided that this notice is preserved and that due credit is given 23 * to the University of Michigan at Ann Arbor. The name of the 24 * University may not be used to endorse or promote products derived 25 * from this software without specific prior written permission. This 26 * software is provided ``as is'' without express or implied warranty. 27 */ 28/* This work was originally developed by the University of Michigan 29 * and distributed as part of U-MICH LDAP. 30 */ 31 32#include <sys/cdefs.h> 33__RCSID("$NetBSD: lbase64.c,v 1.2 2021/08/14 16:14:56 christos Exp $"); 34 35#include "portable.h" 36 37#include "ldap-int.h" 38 39#define RIGHT2 0x03 40#define RIGHT4 0x0f 41 42static const unsigned char b642nib[0x80] = { 43 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 44 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 45 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 46 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 47 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 48 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, 49 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 50 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 51 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 52 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 53 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 54 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 55 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 56 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 57 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 58 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff 59}; 60 61int 62ldap_int_decode_b64_inplace( struct berval *value ) 63{ 64 char *p, *end, *byte; 65 char nib; 66 67 byte = value->bv_val; 68 end = value->bv_val + value->bv_len; 69 70 for ( p = value->bv_val, value->bv_len = 0; 71 p < end; 72 p += 4, value->bv_len += 3 ) 73 { 74 int i; 75 for ( i = 0; i < 4; i++ ) { 76 if ( p[i] != '=' && (p[i] & 0x80 || 77 b642nib[ p[i] & 0x7f ] > 0x3f) ) { 78 Debug2( LDAP_DEBUG_ANY, 79 _("ldap_pvt_decode_b64_inplace: invalid base64 encoding" 80 " char (%c) 0x%x\n"), p[i], p[i] ); 81 return( -1 ); 82 } 83 } 84 85 /* first digit */ 86 nib = b642nib[ p[0] & 0x7f ]; 87 byte[0] = nib << 2; 88 /* second digit */ 89 nib = b642nib[ p[1] & 0x7f ]; 90 byte[0] |= nib >> 4; 91 byte[1] = (nib & RIGHT4) << 4; 92 /* third digit */ 93 if ( p[2] == '=' ) { 94 value->bv_len += 1; 95 break; 96 } 97 nib = b642nib[ p[2] & 0x7f ]; 98 byte[1] |= nib >> 2; 99 byte[2] = (nib & RIGHT2) << 6; 100 /* fourth digit */ 101 if ( p[3] == '=' ) { 102 value->bv_len += 2; 103 break; 104 } 105 nib = b642nib[ p[3] & 0x7f ]; 106 byte[2] |= nib; 107 108 byte += 3; 109 } 110 value->bv_val[ value->bv_len ] = '\0'; 111 112 return LDAP_SUCCESS; 113} 114