PEM.cpp 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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 (b64decoded.is_error()) {
  35. dbgln("Failed to decode PEM: {}", b64decoded.error().string_literal());
  36. return {};
  37. }
  38. if (decoded.try_append(b64decoded.value().data(), b64decoded.value().size()).is_error()) {
  39. dbgln("Failed to decode PEM, likely OOM condition");
  40. return {};
  41. }
  42. break;
  43. }
  44. case Ended:
  45. lexer.consume_all();
  46. break;
  47. default:
  48. VERIFY_NOT_REACHED();
  49. }
  50. }
  51. return decoded;
  52. }
  53. }