armor.c 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #include <linux/errno.h>
  2. int ceph_armor(char *dst, const char *src, const char *end);
  3. int ceph_unarmor(char *dst, const char *src, const char *end);
  4. /*
  5. * base64 encode/decode.
  6. */
  7. static const char *pem_key =
  8. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  9. static int encode_bits(int c)
  10. {
  11. return pem_key[c];
  12. }
  13. static int decode_bits(char c)
  14. {
  15. if (c >= 'A' && c <= 'Z')
  16. return c - 'A';
  17. if (c >= 'a' && c <= 'z')
  18. return c - 'a' + 26;
  19. if (c >= '0' && c <= '9')
  20. return c - '0' + 52;
  21. if (c == '+')
  22. return 62;
  23. if (c == '/')
  24. return 63;
  25. if (c == '=')
  26. return 0; /* just non-negative, please */
  27. return -EINVAL;
  28. }
  29. int ceph_armor(char *dst, const char *src, const char *end)
  30. {
  31. int olen = 0;
  32. int line = 0;
  33. while (src < end) {
  34. unsigned char a, b, c;
  35. a = *src++;
  36. *dst++ = encode_bits(a >> 2);
  37. if (src < end) {
  38. b = *src++;
  39. *dst++ = encode_bits(((a & 3) << 4) | (b >> 4));
  40. if (src < end) {
  41. c = *src++;
  42. *dst++ = encode_bits(((b & 15) << 2) |
  43. (c >> 6));
  44. *dst++ = encode_bits(c & 63);
  45. } else {
  46. *dst++ = encode_bits((b & 15) << 2);
  47. *dst++ = '=';
  48. }
  49. } else {
  50. *dst++ = encode_bits(((a & 3) << 4));
  51. *dst++ = '=';
  52. *dst++ = '=';
  53. }
  54. olen += 4;
  55. line += 4;
  56. if (line == 64) {
  57. line = 0;
  58. *(dst++) = '\n';
  59. olen++;
  60. }
  61. }
  62. return olen;
  63. }
  64. int ceph_unarmor(char *dst, const char *src, const char *end)
  65. {
  66. int olen = 0;
  67. while (src < end) {
  68. int a, b, c, d;
  69. if (src[0] == '\n') {
  70. src++;
  71. continue;
  72. }
  73. if (src + 4 > end)
  74. return -EINVAL;
  75. a = decode_bits(src[0]);
  76. b = decode_bits(src[1]);
  77. c = decode_bits(src[2]);
  78. d = decode_bits(src[3]);
  79. if (a < 0 || b < 0 || c < 0 || d < 0)
  80. return -EINVAL;
  81. *dst++ = (a << 2) | (b >> 4);
  82. if (src[2] == '=')
  83. return olen + 1;
  84. *dst++ = ((b & 15) << 4) | (c >> 2);
  85. if (src[3] == '=')
  86. return olen + 2;
  87. *dst++ = ((c & 3) << 6) | d;
  88. olen += 3;
  89. src += 4;
  90. }
  91. return olen;
  92. }