ROBODoc documented the SILC Hash Interface and improved
[silc.git] / lib / silccrypt / silcpkcs.c
index 8d409e35ec8792198c54171d0a362ca500b6b79f..0a5bd31bad465cdf72faa422f10fe8f18d015517 100644 (file)
@@ -361,7 +361,7 @@ int silc_pkcs_sign_with_hash(SilcPKCS pkcs, SilcHash hash,
   int ret;
 
   silc_hash_make(hash, src, src_len, hashr);
-  hash_len = hash->hash->hash_len;
+  hash_len = silc_hash_len(hash);
 
   SILC_LOG_HEXDUMP(("Hash"), hashr, hash_len);
 
@@ -385,7 +385,7 @@ int silc_pkcs_verify_with_hash(SilcPKCS pkcs, SilcHash hash,
   int ret;
 
   silc_hash_make(hash, data, data_len, hashr);
-  hash_len = hash->hash->hash_len;
+  hash_len = silc_hash_len(hash);
 
   SILC_LOG_HEXDUMP(("Hash"), hashr, hash_len);
 
@@ -406,17 +406,16 @@ char *silc_pkcs_encode_identifier(char *username, char *host, char *realname,
   SilcBuffer buf;
   char *identifier;
   SilcUInt32 len, tlen = 0;
-  char utf8[256 + 1];
 
   if (!username || !host)
     return NULL;
 
-  len = (username ? silc_utf8_encoded_len(username, strlen(username), 0) : 0) +
-       (host     ? silc_utf8_encoded_len(host, strlen(host), 0) : 0) +
-       (realname ? silc_utf8_encoded_len(realname, strlen(realname), 0) : 0) +
-       (email    ? silc_utf8_encoded_len(email, strlen(email), 0) : 0) +
-       (org      ? silc_utf8_encoded_len(org, strlen(org), 0) : 0) +
-       (country  ? silc_utf8_encoded_len(country, strlen(country), 0) : 0);
+  len = (username ? strlen(username) : 0) +
+       (host     ? strlen(host)     : 0) +
+       (realname ? strlen(realname) : 0) +
+       (email    ? strlen(email)    : 0) +
+       (org      ? strlen(org)      : 0) +
+       (country  ? strlen(country)  : 0);
   
   if (len < 3)
     return NULL;
@@ -426,77 +425,62 @@ char *silc_pkcs_encode_identifier(char *username, char *host, char *realname,
   silc_buffer_pull_tail(buf, len);
 
   if (username) {
-    memset(utf8, 0, sizeof(utf8));
-    len = silc_utf8_encode(username, strlen(username), 0, utf8,
-                          sizeof(utf8) - 1);
     silc_buffer_format(buf,
                       SILC_STR_UI32_STRING("UN="),
-                      SILC_STR_UI32_STRING(utf8),
+                      SILC_STR_UI32_STRING(username),
                       SILC_STR_END);
-    silc_buffer_pull(buf, 3 + len);
-    tlen = 3 + len
+    silc_buffer_pull(buf, 3 + strlen(username));
+    tlen = 3 + strlen(username)
   }
     
   if (host) {
-    memset(utf8, 0, sizeof(utf8));
-    len = silc_utf8_encode(host, strlen(host), 0, utf8, sizeof(utf8) - 1);
     silc_buffer_format(buf,
                       SILC_STR_UI32_STRING(", "),
                       SILC_STR_UI32_STRING("HN="),
-                      SILC_STR_UI32_STRING(utf8),
+                      SILC_STR_UI32_STRING(host),
                       SILC_STR_END);
-    silc_buffer_pull(buf, 5 + len);
-    tlen += 5 + len
+    silc_buffer_pull(buf, 5 + strlen(host));
+    tlen += 5 + strlen(host)
   }
 
   if (realname) {
-    memset(utf8, 0, sizeof(utf8));
-    len = silc_utf8_encode(realname, strlen(realname), 0, utf8,
-                          sizeof(utf8) - 1);
     silc_buffer_format(buf,
                       SILC_STR_UI32_STRING(", "),
                       SILC_STR_UI32_STRING("RN="),
-                      SILC_STR_UI32_STRING(utf8),
+                      SILC_STR_UI32_STRING(realname),
                       SILC_STR_END);
-    silc_buffer_pull(buf, 5 + len);
-    tlen += 5 + len
+    silc_buffer_pull(buf, 5 + strlen(realname));
+    tlen += 5 + strlen(realname)
   }
 
   if (email) {
-    memset(utf8, 0, sizeof(utf8));
-    len = silc_utf8_encode(email, strlen(email), 0, utf8, sizeof(utf8) - 1);
     silc_buffer_format(buf,
                       SILC_STR_UI32_STRING(", "),
                       SILC_STR_UI32_STRING("E="),
-                      SILC_STR_UI32_STRING(utf8),
+                      SILC_STR_UI32_STRING(email),
                       SILC_STR_END);
-    silc_buffer_pull(buf, 4 + len);
-    tlen += 4 + len
+    silc_buffer_pull(buf, 4 + strlen(email));
+    tlen += 4 + strlen(email)
   }
 
   if (org) {
-    memset(utf8, 0, sizeof(utf8));
-    len = silc_utf8_encode(org, strlen(org), 0, utf8, sizeof(utf8) - 1);
     silc_buffer_format(buf,
                       SILC_STR_UI32_STRING(", "),
                       SILC_STR_UI32_STRING("O="),
-                      SILC_STR_UI32_STRING(utf8),
+                      SILC_STR_UI32_STRING(org),
                       SILC_STR_END);
-    silc_buffer_pull(buf, 4 + len);
-    tlen += 4 + len
+    silc_buffer_pull(buf, 4 + strlen(org));
+    tlen += 4 + strlen(org)
   }
 
   if (country) {
-    memset(utf8, 0, sizeof(utf8));
-    len = silc_utf8_encode(country, strlen(country), 0, utf8,
-                          sizeof(utf8) - 1);
     silc_buffer_format(buf,
                       SILC_STR_UI32_STRING(", "),
                       SILC_STR_UI32_STRING("C="),
-                      SILC_STR_UI32_STRING(utf8),
+                      SILC_STR_UI32_STRING(country),
                       SILC_STR_END);
-    silc_buffer_pull(buf, 4 + len);
-    tlen += 4 + len
+    silc_buffer_pull(buf, 4 + strlen(country));
+    tlen += 4 + strlen(country)
   }
 
   silc_buffer_push(buf, buf->data - buf->head);
@@ -581,15 +565,25 @@ SilcPublicKey silc_pkcs_public_key_alloc(char *name, char *identifier,
                                         SilcUInt32 pk_len)
 {
   SilcPublicKey public_key;
+  char *tmp = NULL;
 
   public_key = silc_calloc(1, sizeof(*public_key));
-  public_key->len = 4 + 2 + strlen(name) + 2 + strlen(identifier) + pk_len;
   public_key->name = strdup(name);
-  public_key->identifier = strdup(identifier);
   public_key->pk_len = pk_len;
   public_key->pk = silc_calloc(pk_len, sizeof(*public_key->pk));
   memcpy(public_key->pk, pk, pk_len);
 
+  if (!silc_utf8_valid(identifier, strlen(identifier))) {
+    int len = silc_utf8_encoded_len(identifier, strlen(identifier), 0);
+    tmp = silc_calloc(len + 1, sizeof(*tmp));
+    silc_utf8_encode(identifier, strlen(identifier), 0, tmp, len);
+    identifier = tmp;
+  }
+
+  public_key->identifier = strdup(identifier);
+  public_key->len = 4 + 2 + strlen(name) + 2 + strlen(identifier) + pk_len;
+  silc_free(tmp);
+
   return public_key;
 }
 
@@ -817,6 +811,25 @@ bool silc_pkcs_public_key_compare(SilcPublicKey key1, SilcPublicKey key2)
   return FALSE;
 }
 
+/* Copies the public key indicated by `public_key' and returns new allocated
+   public key which is indentical to the `public_key'. */
+
+SilcPublicKey silc_pkcs_public_key_copy(SilcPublicKey public_key)
+{
+  SilcPublicKey key = silc_calloc(1, sizeof(*key));
+  if (!key)
+    return NULL;
+
+  key->len = public_key->len;
+  key->name = silc_memdup(public_key->name, strlen(public_key->name));
+  key->identifier = silc_memdup(public_key->identifier,
+                               strlen(public_key->identifier));
+  key->pk = silc_memdup(public_key->pk, public_key->pk_len);
+  key->pk_len = public_key->pk_len;
+
+  return key;
+}
+
 /* Encodes SILC private key from SilcPrivateKey. Returns the encoded data. */
 
 unsigned char *