lbase64.c 3.1 KB

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