diff --git a/examples/sexp-conv.c b/examples/sexp-conv.c
index 5ae47b1daeeba7fbd9ae73dc08a480af7f2e7397..a1283b87eac514097a5a027deb206f4e6dbb13b9 100644
--- a/examples/sexp-conv.c
+++ b/examples/sexp-conv.c
@@ -52,27 +52,20 @@ enum sexp_token
     SEXP_LIST_START,
     SEXP_LIST_END,
     SEXP_TRANSPORT_START,
-    SEXP_TRANSPORT_END,
+    SEXP_CODING_END,
     SEXP_EOF,
   };
 
-enum sexp_coding
-  {
-    SEXP_PLAIN,
-    SEXP_BASE64,
-    SEXP_HEX,
-  };
-
 struct sexp_input
 {
   FILE *f;
 
-  enum sexp_coding coding;
-  /* Used in transport mode */
+  const struct nettle_armor *coding;
+
   union {
     struct base64_decode_ctx base64;
     struct base16_decode_ctx hex;
-  };
+  } state;
 
   /* Terminator for current coding */
   uint8_t terminator;
@@ -91,7 +84,7 @@ static void
 sexp_input_init(struct sexp_input *input, FILE *f)
 {
   input->f = f;
-  input->coding = SEXP_PLAIN;
+  input->coding = NULL;
   input->level = 0;
 
   nettle_buffer_init(&input->string);
@@ -146,46 +139,68 @@ sexp_get_raw_char(struct sexp_input *input, uint8_t *out)
 static int
 sexp_get_char(struct sexp_input *input, uint8_t *out)
 {
-  switch (input->coding)
-    {
-    case SEXP_BASE64:
-      for (;;)
-	{
-	  int done;
-	  uint8_t c;
-	  
-	  if (!sexp_get_raw_char(input, &c))
-	    die("Unexpected end of file in base64 data.\n");
-
-	  if (c == '}')
-	    {
-	      if (base64_decode_final(&input->base64))
-		{
-		  input->token = SEXP_TRANSPORT_END;
-		  return 0;
-		}
-	      else
-		die("Invalid base64 data.\n");
-	    }
+  if (input->coding)
+    for (;;)
+      {
+	int done;
+	uint8_t c;
+	
+	if (!sexp_get_raw_char(input, &c))
+	  die("Unexpected end of file in coded data.\n");
 
-	  done = base64_decode_single(&input->base64, out, c);
-	  if (done)
-	    return 1;
-	}
-    case SEXP_PLAIN:
+	if (c == input->terminator)
+	  {
+	    if (input->coding->decode_final(&input->state))
+	      {
+		input->token = SEXP_CODING_END;
+		return 0;
+	      }
+	    else
+	      die("Invalid coded data.\n");
+	  }
+	done = 1;
+	
+	if (!input->coding->decode_update(&input->state, &done, out, 1, &c))
+	  die("Invalid coded data.\n");
+	  
+	if (done)
+	  return 1;
+      }
+  else
+    {
       if (sexp_get_raw_char(input, out))
 	return 1;
       
       input->token = SEXP_EOF;
       return 0;
+    }
+}
 
-    case SEXP_HEX:
-      /* Not yet implemented */
-      abort();
+static unsigned
+sexp_input_start_coding(struct sexp_input *input,
+			const struct nettle_armor *coding,
+			uint8_t terminator)
+{
+  unsigned old_level = input->level;
+  
+  assert(!input->coding);
+  
+  input->coding = coding;
+  input->coding->decode_init(&input->state);
+  input->terminator = terminator;
+  input->level = 0;
 
-    default:
-      abort();
-    }
+  return old_level;
+}
+
+static void
+sexp_input_end_coding(struct sexp_input *input,
+		      unsigned old_level)
+{
+  assert(input->coding);
+
+  input->coding = NULL;
+  input->level = old_level;
 }
 
 static const char
@@ -214,6 +229,7 @@ token_chars[0x80] =
 static uint8_t
 sexp_get_token_char(struct sexp_input *input)
 {
+  /* FIXME: Use sexp_get_char */
   int c = getc(input->f);
   if (c >= 0 && TOKEN_CHAR(c))
     return c;
@@ -273,7 +289,7 @@ sexp_get_quoted_string(struct sexp_input *input)
 {
   uint8_t c;
 
-  assert(input->coding == SEXP_PLAIN);
+  assert(!input->coding);
   
   while (sexp_get_quoted_char(input, &c))
     if (!NETTLE_BUFFER_PUTC(&input->string, c))
@@ -290,47 +306,31 @@ sexp_get_hex_string(struct sexp_input *input)
 static void
 sexp_get_base64_string(struct sexp_input *input)
 {
-  struct base64_decode_ctx ctx;
-
-  assert(input->coding == SEXP_PLAIN);
+  unsigned old_level 
+    = sexp_input_start_coding(input, &nettle_base64, '|');
 
-  base64_decode_init(&ctx);
-  
   for (;;)
     {
       uint8_t c;
-      uint8_t decoded;
       
       if (!sexp_get_char(input, &c))
-	die("Unexpected end of file in base64 string.\n");
-
-      if (c == '|')
 	{
-	  if (!base64_decode_final(&ctx))
-	    die("Invalid base64 string.\n");
+	  if (input->token != SEXP_CODING_END)
+	    die("Unexpected end of file in base64 string.\n");
+
+	  sexp_input_end_coding(input, old_level);
 	  return;
 	}
       
-      switch(base64_decode_single(&ctx, &decoded, c))
-	{
-	case 0:
-	  break;
-	case 1:
-	  if (!NETTLE_BUFFER_PUTC(&input->string, decoded))
-	    die("Virtual memory exhasuted.\n");
-	  break;
-	case -1:
-	  die("Invalid base64 string.\n");
-	default:
-	  abort();
-	}
+      if (!NETTLE_BUFFER_PUTC(&input->string, c))
+	die("Virtual memory exhasuted.\n");
     }
 }
 
 static void
 sexp_get_token_string(struct sexp_input *input, uint8_t c)
 {
-  assert(input->coding == SEXP_PLAIN);
+  assert(!input->coding);
 
   if (!TOKEN_CHAR(c) || ! NETTLE_BUFFER_PUTC(&input->string, c))
     die("Invalid token.\n");
@@ -464,6 +464,10 @@ sexp_get_token(struct sexp_input *input, enum sexp_mode mode)
 	  input->token = SEXP_DISPLAY_END;
 	  return;
 
+	case '{':
+	  input->token = SEXP_TRANSPORT_START;
+	  return;
+	  
 	case ' ':  /* SPC, TAB, LF, CR */
 	case '\t':
 	case '\n':
@@ -757,10 +761,7 @@ sexp_convert_list(struct sexp_input *input, enum sexp_mode mode_in,
     {
       sexp_get_token(input, mode_in);
   
-      /* Check for end of list */
-      if (input->token == SEXP_LIST_END
-	  || input->token == SEXP_EOF
-	  || input->token == SEXP_TRANSPORT_END)
+      if (input->token == SEXP_LIST_END)
 	return;
 
       if (mode_out == SEXP_ADVANCED)
@@ -861,6 +862,7 @@ sexp_convert_item(struct sexp_input *input, enum sexp_mode mode_in,
     case SEXP_STRING:
       sexp_put_string(output, mode_out, &input->string);
       break;
+
     case SEXP_DISPLAY_START:
       sexp_put_display_start(output);
       sexp_convert_string(input, mode_in, output, mode_out);
@@ -874,28 +876,19 @@ sexp_convert_item(struct sexp_input *input, enum sexp_mode mode_in,
 	die("Base64 not allowed in canonical mode.\n");
       else
 	{
-	  unsigned old_level = input->level;
-	  assert(input->coding == SEXP_PLAIN);
+	  unsigned old_level
+	    = sexp_input_start_coding(input, &nettle_base64, '}');
+	  sexp_get_token(input, SEXP_CANONICAL);
 	  
-	  input->coding = SEXP_BASE64;
-	  input->level = 0;
-
-	  base64_decode_init(&input->base64);
-
-	  /* FIXME: sexp_convert_list is wrong. */
-	  sexp_convert_list(input, SEXP_CANONICAL, output, mode_out, indent);
+	  sexp_convert_item(input, SEXP_CANONICAL, output, mode_out, indent);
+	  sexp_skip_token(input, SEXP_CANONICAL, SEXP_CODING_END);
+	  sexp_input_end_coding(input, old_level);
 	  
-	  input->coding = SEXP_PLAIN;
-	  input->level = old_level;
 	  break;
 	}
-    case SEXP_TRANSPORT_END:
-      /* FIXME: Should be moved do sexp_convert_transport */
-      if ( (input->coding != SEXP_BASE64)
-	   || input->level || !base64_decode_final(&input->base64))
-	die("Invalid base64.\n");
+    case SEXP_CODING_END:
+      die("Unexpected end of coding.\n");
 
-      break;
     default:
       die("Syntax error.\n");
     }