e_rc4_hmac_md5.c: oops, can't use rc4_hmac_md5_cipher on legacy Intel CPUs.
[openssl.git] / crypto / asn1 / p8_pkey.c
index 24b409132f53af1627675ccaf9dd3e363ba8d5a0..17b68d386d8509b147fb0752aa6c50681a8a2949 100644 (file)
@@ -1,9 +1,9 @@
 /* p8_pkey.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -62,7 +62,8 @@
 #include <openssl/x509.h>
 
 /* Minor tweak to operation: zero private key data */
-static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
+static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                                                       void *exarg)
 {
        /* Since the structure must still be valid use ASN1_OP_FREE_PRE */
        if(operation == ASN1_OP_FREE_PRE) {
@@ -82,3 +83,73 @@ ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
 } ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
 
 IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
+                                       int version,
+                                       int ptype, void *pval,
+                                       unsigned char *penc, int penclen)
+       {
+       unsigned char **ppenc = NULL;
+       if (version >= 0)
+               {
+               if (!ASN1_INTEGER_set(priv->version, version))
+                       return 0;
+               }
+       if (penc)
+               {
+               int pmtype;
+               ASN1_OCTET_STRING *oct;
+               oct = ASN1_OCTET_STRING_new();
+               if (!oct)
+                       return 0;
+               oct->data = penc;
+               ppenc = &oct->data;
+               oct->length = penclen;
+               if (priv->broken == PKCS8_NO_OCTET)
+                       pmtype = V_ASN1_SEQUENCE;
+               else
+                       pmtype = V_ASN1_OCTET_STRING;
+               ASN1_TYPE_set(priv->pkey, pmtype, oct);
+               }
+       if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval))
+               {
+               /* If call fails do not swallow 'enc' */
+               if (ppenc)
+                       *ppenc = NULL;
+               return 0;
+               }
+       return 1;
+       }
+
+int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
+               const unsigned char **pk, int *ppklen,
+               X509_ALGOR **pa,
+               PKCS8_PRIV_KEY_INFO *p8)
+       {
+       if (ppkalg)
+               *ppkalg = p8->pkeyalg->algorithm;
+       if(p8->pkey->type == V_ASN1_OCTET_STRING)
+               {
+               p8->broken = PKCS8_OK;
+               if (pk)
+                       {
+                       *pk = p8->pkey->value.octet_string->data;
+                       *ppklen = p8->pkey->value.octet_string->length;
+                       }
+               }
+       else if (p8->pkey->type == V_ASN1_SEQUENCE)
+               {
+               p8->broken = PKCS8_NO_OCTET;
+               if (pk)
+                       {
+                       *pk = p8->pkey->value.sequence->data;
+                       *ppklen = p8->pkey->value.sequence->length;
+                       }
+               }
+       else
+               return 0;
+       if (pa)
+               *pa = p8->pkeyalg;
+       return 1;
+       }
+