PEM.cpp 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. /*
  2. * Copyright (c) 2021, the SerenityOS developers.
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Base64.h>
  7. #include <AK/GenericLexer.h>
  8. #include <LibCrypto/ASN1/PEM.h>
  9. namespace Crypto {
  10. ByteBuffer decode_pem(ReadonlyBytes data)
  11. {
  12. GenericLexer lexer { data };
  13. ByteBuffer decoded;
  14. // FIXME: Parse multiple.
  15. enum {
  16. PreStartData,
  17. Started,
  18. Ended,
  19. } state { PreStartData };
  20. while (!lexer.is_eof()) {
  21. switch (state) {
  22. case PreStartData:
  23. if (lexer.consume_specific("-----BEGIN"))
  24. state = Started;
  25. lexer.consume_line();
  26. break;
  27. case Started: {
  28. if (lexer.consume_specific("-----END")) {
  29. state = Ended;
  30. lexer.consume_line();
  31. break;
  32. }
  33. auto b64decoded = decode_base64(lexer.consume_line().trim_whitespace(TrimMode::Right));
  34. if (!decoded.try_append(b64decoded.data(), b64decoded.size())) {
  35. dbgln("Failed to decode PEM, likely OOM condition");
  36. return {};
  37. }
  38. break;
  39. }
  40. case Ended:
  41. lexer.consume_all();
  42. break;
  43. default:
  44. VERIFY_NOT_REACHED();
  45. }
  46. }
  47. return decoded;
  48. }
  49. }