Base64URLEncoder and Base64URLDecoder classes

43 views
Skip to first unread message

Jeffrey Walton

unread,
Jun 30, 2015, 11:12:17 PM6/30/15
to cryptop...@googlegroups.com
Is anyone opposed to committing Base64URLEncoder and Base64URLDecoder classes?

They are useful when interop'ing with web based gear, like JSON Web Keys (JWKs).

The patch is below. The documentation is available at http://www.cryptopp.com/wiki/Base64URLEncoder.

**********

Index: base64.h
===================================================================
--- base64.h    (revision 541)
+++ base64.h    (working copy)
@@ -5,7 +5,8 @@
 
 NAMESPACE_BEGIN(CryptoPP)
 
-//! Base64 Encoder Class
+//! Base64 Encoder Class
+// https://tools.ietf.org/html/rfc4648#section-4
 class Base64Encoder : public SimpleProxyFilter
 {
 public:
@@ -14,19 +15,47 @@
     {
         IsolatedInitialize(MakeParameters(Name::InsertLineBreaks(), insertLineBreaks)(Name::MaxLineLength(), maxLineLength));
     }
-
+   
     void IsolatedInitialize(const NameValuePairs &parameters);
 };
 
-//! Base64 Decoder Class
+//! Base64 Decoder Class
+// https://tools.ietf.org/html/rfc4648#section-4
 class Base64Decoder : public BaseN_Decoder
 {
 public:
     Base64Decoder(BufferedTransformation *attachment = NULL)
         : BaseN_Decoder(GetDecodingLookupArray(), 6, attachment) {}
+   
+    void IsolatedInitialize(const NameValuePairs &parameters) {}
+   
+private:
+    static const int * CRYPTOPP_API GetDecodingLookupArray();
+};
 
+//! Base64 URL Encoder Class
+// https://tools.ietf.org/html/rfc4648#section-5
+class Base64URLEncoder : public SimpleProxyFilter
+{
+public:
+    Base64URLEncoder(BufferedTransformation *attachment = NULL, bool insertLineBreaks = false, int maxLineLength = -1)
+        : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment)
+    {
+        IsolatedInitialize(MakeParameters(Name::InsertLineBreaks(), insertLineBreaks)(Name::MaxLineLength(), maxLineLength));
+    }
+   
+    void IsolatedInitialize(const NameValuePairs &parameters);
+};
+
+//! Base64 URL Decoder Class
+class Base64URLDecoder : public BaseN_Decoder
+{
+public:
+    Base64URLDecoder(BufferedTransformation *attachment = NULL)
+        : BaseN_Decoder(GetDecodingLookupArray(), 6, attachment) {}
+   
     void IsolatedInitialize(const NameValuePairs &parameters) {}
-
+   
 private:
     static const int * CRYPTOPP_API GetDecodingLookupArray();
 };
Index: base64.cpp
===================================================================
--- base64.cpp    (revision 541)
+++ base64.cpp    (working copy)
@@ -5,8 +5,13 @@
 
 NAMESPACE_BEGIN(CryptoPP)
 
-static const byte s_vec[] =
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+// Base64
+static const byte s_vec1[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+// Base64URL
+static const byte s_vec2[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
 static const byte s_padding = '=';
 
 void Base64Encoder::IsolatedInitialize(const NameValuePairs &parameters)
@@ -18,7 +23,7 @@
    
     m_filter->Initialize(CombinedNameValuePairs(
         parameters,
-        MakeParameters(Name::EncodingLookupArray(), &s_vec[0], false)
+        MakeParameters(Name::EncodingLookupArray(), &s_vec1[0], false)
             (Name::PaddingByte(), s_padding)
             (Name::GroupSize(), insertLineBreaks ? maxLineLength : 0)
             (Name::Separator(), ConstByteArrayParameter(lineBreak))
@@ -26,14 +31,44 @@
             (Name::Log2Base(), 6, true)));
 }
 
+void Base64URLEncoder::IsolatedInitialize(const NameValuePairs &parameters)
+{
+    bool insertLineBreaks = parameters.GetValueWithDefault(Name::InsertLineBreaks(), true);
+    int maxLineLength = parameters.GetIntValueWithDefault(Name::MaxLineLength(), 72);
+   
+    const char *lineBreak = insertLineBreaks ? "\n" : "";
+   
+    m_filter->Initialize(CombinedNameValuePairs(
+        parameters,
+        MakeParameters(Name::EncodingLookupArray(), &s_vec2[0], false)
+            (Name::PaddingByte(), s_padding)
+            (Name::GroupSize(), insertLineBreaks ? maxLineLength : 0)
+            (Name::Separator(), ConstByteArrayParameter(lineBreak))
+            (Name::Terminator(), ConstByteArrayParameter(lineBreak))
+            (Name::Log2Base(), 6, true)));
+}
+
 const int *Base64Decoder::GetDecodingLookupArray()
 {
     static volatile bool s_initialized = false;
     static int s_array[256];
+   
+    if (!s_initialized)
+    {
+        InitializeDecodingLookupArray(s_array, s_vec1, 64, false);
+        s_initialized = true;
+    }
+    return s_array;
+}
 
+const int *Base64URLDecoder::GetDecodingLookupArray()
+{
+    static volatile bool s_initialized = false;
+    static int s_array[256];
+   
     if (!s_initialized)
     {
-        InitializeDecodingLookupArray(s_array, s_vec, 64, false);
+        InitializeDecodingLookupArray(s_array, s_vec2, 64, false);
         s_initialized = true;
     }
     return s_array;

Mobile Mouse

unread,
Jul 1, 2015, 8:05:54 PM7/1/15
to Jeffrey Walton, cryptop...@googlegroups.com
About time somebody did it.  ;)


--
--
You received this message because you are subscribed to the "Crypto++ Users" Google Group.
To unsubscribe, send an email to cryptopp-user...@googlegroups.com.
More information about Crypto++ and this group is available at http://www.cryptopp.com.
---
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-user...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Jeffrey Walton

unread,
Jul 1, 2015, 9:01:05 PM7/1/15
to cryptop...@googlegroups.com, nolo...@gmail.com


On Wednesday, July 1, 2015 at 8:05:54 PM UTC-4, Mouse wrote:
About time somebody did it.  ;)
Reply all
Reply to author
Forward
0 new messages