2
0

ct_b64.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. /*
  2. * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <limits.h>
  10. #include <string.h>
  11. #include <openssl/ct.h>
  12. #include <openssl/err.h>
  13. #include <openssl/evp.h>
  14. #include "ct_local.h"
  15. /*
  16. * Decodes the base64 string |in| into |out|.
  17. * A new string will be malloc'd and assigned to |out|. This will be owned by
  18. * the caller. Do not provide a pre-allocated string in |out|.
  19. */
  20. static int ct_base64_decode(const char *in, unsigned char **out)
  21. {
  22. size_t inlen = strlen(in);
  23. int outlen, i;
  24. unsigned char *outbuf = NULL;
  25. if (inlen == 0) {
  26. *out = NULL;
  27. return 0;
  28. }
  29. outlen = (inlen / 4) * 3;
  30. outbuf = OPENSSL_malloc(outlen);
  31. if (outbuf == NULL) {
  32. CTerr(CT_F_CT_BASE64_DECODE, ERR_R_MALLOC_FAILURE);
  33. goto err;
  34. }
  35. outlen = EVP_DecodeBlock(outbuf, (unsigned char *)in, inlen);
  36. if (outlen < 0) {
  37. CTerr(CT_F_CT_BASE64_DECODE, CT_R_BASE64_DECODE_ERROR);
  38. goto err;
  39. }
  40. /* Subtract padding bytes from |outlen|. Any more than 2 is malformed. */
  41. i = 0;
  42. while (in[--inlen] == '=') {
  43. --outlen;
  44. if (++i > 2)
  45. goto err;
  46. }
  47. *out = outbuf;
  48. return outlen;
  49. err:
  50. OPENSSL_free(outbuf);
  51. return -1;
  52. }
  53. SCT *SCT_new_from_base64(unsigned char version, const char *logid_base64,
  54. ct_log_entry_type_t entry_type, uint64_t timestamp,
  55. const char *extensions_base64,
  56. const char *signature_base64)
  57. {
  58. SCT *sct = SCT_new();
  59. unsigned char *dec = NULL;
  60. const unsigned char* p = NULL;
  61. int declen;
  62. if (sct == NULL) {
  63. CTerr(CT_F_SCT_NEW_FROM_BASE64, ERR_R_MALLOC_FAILURE);
  64. return NULL;
  65. }
  66. /*
  67. * RFC6962 section 4.1 says we "MUST NOT expect this to be 0", but we
  68. * can only construct SCT versions that have been defined.
  69. */
  70. if (!SCT_set_version(sct, version)) {
  71. CTerr(CT_F_SCT_NEW_FROM_BASE64, CT_R_SCT_UNSUPPORTED_VERSION);
  72. goto err;
  73. }
  74. declen = ct_base64_decode(logid_base64, &dec);
  75. if (declen < 0) {
  76. CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
  77. goto err;
  78. }
  79. if (!SCT_set0_log_id(sct, dec, declen))
  80. goto err;
  81. dec = NULL;
  82. declen = ct_base64_decode(extensions_base64, &dec);
  83. if (declen < 0) {
  84. CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
  85. goto err;
  86. }
  87. SCT_set0_extensions(sct, dec, declen);
  88. dec = NULL;
  89. declen = ct_base64_decode(signature_base64, &dec);
  90. if (declen < 0) {
  91. CTerr(CT_F_SCT_NEW_FROM_BASE64, X509_R_BASE64_DECODE_ERROR);
  92. goto err;
  93. }
  94. p = dec;
  95. if (o2i_SCT_signature(sct, &p, declen) <= 0)
  96. goto err;
  97. OPENSSL_free(dec);
  98. dec = NULL;
  99. SCT_set_timestamp(sct, timestamp);
  100. if (!SCT_set_log_entry_type(sct, entry_type))
  101. goto err;
  102. return sct;
  103. err:
  104. OPENSSL_free(dec);
  105. SCT_free(sct);
  106. return NULL;
  107. }
  108. /*
  109. * Allocate, build and returns a new |ct_log| from input |pkey_base64|
  110. * It returns 1 on success,
  111. * 0 on decoding failure, or invalid parameter if any
  112. * -1 on internal (malloc) failure
  113. */
  114. int CTLOG_new_from_base64(CTLOG **ct_log, const char *pkey_base64, const char *name)
  115. {
  116. unsigned char *pkey_der = NULL;
  117. int pkey_der_len;
  118. const unsigned char *p;
  119. EVP_PKEY *pkey = NULL;
  120. if (ct_log == NULL) {
  121. CTerr(CT_F_CTLOG_NEW_FROM_BASE64, ERR_R_PASSED_INVALID_ARGUMENT);
  122. return 0;
  123. }
  124. pkey_der_len = ct_base64_decode(pkey_base64, &pkey_der);
  125. if (pkey_der_len < 0) {
  126. CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY);
  127. return 0;
  128. }
  129. p = pkey_der;
  130. pkey = d2i_PUBKEY(NULL, &p, pkey_der_len);
  131. OPENSSL_free(pkey_der);
  132. if (pkey == NULL) {
  133. CTerr(CT_F_CTLOG_NEW_FROM_BASE64, CT_R_LOG_CONF_INVALID_KEY);
  134. return 0;
  135. }
  136. *ct_log = CTLOG_new(pkey, name);
  137. if (*ct_log == NULL) {
  138. EVP_PKEY_free(pkey);
  139. return 0;
  140. }
  141. return 1;
  142. }