一些有关PEM(PEM_read)的代码

阅读更多

 

typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long);

 

struct crypto_ex_data_st

         {

         STACK_OF(void) *sk;

         int dummy; /* gcc is screwing up this data structure :-( */

         };

 

typedef struct crypto_ex_data_st CRYPTO_EX_DATA;

 

 

struct bio_st

         {

         BIO_METHOD *method;

         /* bio, mode, argp, argi, argl, ret */

         long (*callback)(struct bio_st *,int,const char *,int, long,long);

         char *cb_arg; /* first argument for the callback */

 

         int init;

         int shutdown;

         int flags;  /* extra storage */

         int retry_reason;

         int num;

         void *ptr;

         struct bio_st *next_bio;  /* used by filter BIOs */

         struct bio_st *prev_bio;  /* used by filter BIOs */

         int references;

         unsigned long num_read;

         unsigned long num_write;

 

         CRYPTO_EX_DATA ex_data;

         };

 

 

typedef struct bio_st BIO;

 

 

typedef struct bio_method_st

         {

         int type;

         const char *name;

         int (*bwrite)(BIO *, const char *, int);

         int (*bread)(BIO *, char *, int);

         int (*bputs)(BIO *, const char *);

         int (*bgets)(BIO *, char *, int);

         long (*ctrl)(BIO *, int, long, void *);

         int (*create)(BIO *);

         int (*destroy)(BIO *);

        long (*callback_ctrl)(BIO *, int, bio_info_cb *);

         } BIO_METHOD;

 

static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size)

         {

         int ret=0;

 

         buf[0]='\0';

         if (bp->flags&BIO_FLAGS_UPLINK)

                   {

                   if (!UP_fgets(buf,size,bp->ptr))

                            goto err;

                   }

         else

                   {

                   if (!fgets(buf,size,(FILE *)bp->ptr))

                            goto err;

                   }

         if (buf[0] != '\0')

                   ret=strlen(buf);

         err:

         return(ret);

         }

 

 

static BIO_METHOD methods_filep=

         {

         BIO_TYPE_FILE,

         "FILE pointer",

         file_write,

         file_read,

         file_puts,

         file_gets,

         file_ctrl,

         file_new,

         file_free,

         NULL,

         };

 

BIO_METHOD *BIO_s_file(void)

         {

         return(&methods_filep);

         }

 

BIO *BIO_new(BIO_METHOD *method)

         {

         BIO *ret=NULL;

 

         ret=(BIO *)OPENSSL_malloc(sizeof(BIO));

         if (ret == NULL)

                   {

                   BIOerr(BIO_F_BIO_NEW,ERR_R_MALLOC_FAILURE);

                   return(NULL);

                   }

         if (!BIO_set(ret,method))

                   {

                   OPENSSL_free(ret);

                   ret=NULL;

                   }

         return(ret);

         }

 

long BIO_ctrl(BIO *b, int cmd, long larg, void *parg)

         {

         long ret;

         long (*cb)(BIO *,int,const char *,int,long,long);

 

         if (b == NULL) return(0);

 

         if ((b->method == NULL) || (b->method->ctrl == NULL))

                   {

                   BIOerr(BIO_F_BIO_CTRL,BIO_R_UNSUPPORTED_METHOD);

                   return(-2);

                   }

 

         cb=b->callback;

 

         if ((cb != NULL) &&

                   ((ret=cb(b,BIO_CB_CTRL,parg,cmd,larg,1L)) <= 0))

                   return(ret);

 

         ret=b->method->ctrl(b,cmd,larg,parg);

 

         if (cb != NULL)

                   ret=cb(b,BIO_CB_CTRL|BIO_CB_RETURN,parg,cmd,

                            larg,ret);

         return(ret);

         }

 

 

#define BIO_set_fp(b,fp,c)      BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)

 

int BIO_gets(BIO *b, char *in, int inl)

         {

         int i;

         long (*cb)(BIO *,int,const char *,int,long,long);

 

         if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL))

                   {

                   BIOerr(BIO_F_BIO_GETS,BIO_R_UNSUPPORTED_METHOD);

                   return(-2);

                   }

 

         cb=b->callback;

 

         if ((cb != NULL) &&

                   ((i=(int)cb(b,BIO_CB_GETS,in,inl,0L,1L)) <= 0))

                            return(i);

 

         if (!b->init)

                   {

                   BIOerr(BIO_F_BIO_GETS,BIO_R_UNINITIALIZED);

                   return(-2);

                   }

 

         i=b->method->bgets(b,in,inl);

 

         if (cb != NULL)

                   i=(int)cb(b,BIO_CB_GETS|BIO_CB_RETURN,in,inl,

                            0L,(long)i);

         return(i);

         }

 

 

int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,

              long *len)

         {

         EVP_ENCODE_CTX ctx;

         int end=0,i,k,bl=0,hl=0,nohead=0;

         char buf[256];

         BUF_MEM *nameB;

         BUF_MEM *headerB;

         BUF_MEM *dataB,*tmpB;

        

         nameB=BUF_MEM_new();

         headerB=BUF_MEM_new();

         dataB=BUF_MEM_new();

         if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL))

                   {

                   BUF_MEM_free(nameB);

                   BUF_MEM_free(headerB);

                   BUF_MEM_free(dataB);

                   PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);

                   return(0);

                   }

 

         buf[254]='\0';

         for (;;)

                   {

                   i=BIO_gets(bp,buf,254);

 

                   if (i <= 0)

                            {

                            PEMerr(PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE);

                            goto err;

                            }

 

                   while ((i >= 0) && (buf[i] <= ' ')) i--;

                   buf[++i]='\n'; buf[++i]='\0';

 

                   if (strncmp(buf,"-----BEGIN ",11) == 0)

                            {

                            i=strlen(&(buf[11]));

 

                            if (strncmp(&(buf[11+i-6]),"-----\n",6) != 0)

                                     continue;

                            if (!BUF_MEM_grow(nameB,i+9))

                                     {

                                     PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);

                                     goto err;

                                     }

                            memcpy(nameB->data,&(buf[11]),i-6);

                            nameB->data[i-6]='\0';

                            break;

                            }

                   }

         hl=0;

         if (!BUF_MEM_grow(headerB,256))

                   { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }

         headerB->data[0]='\0';

         for (;;)

                   {

                   i=BIO_gets(bp,buf,254);

                   if (i <= 0) break;

 

                   while ((i >= 0) && (buf[i] <= ' ')) i--;

                   buf[++i]='\n'; buf[++i]='\0';

 

                   if (buf[0] == '\n') break;

                   if (!BUF_MEM_grow(headerB,hl+i+9))

                            { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }

                   if (strncmp(buf,"-----END ",9) == 0)

                            {

                            nohead=1;

                            break;

                            }

                   memcpy(&(headerB->data[hl]),buf,i);

                   headerB->data[hl+i]='\0';

                   hl+=i;

                   }

 

         bl=0;

         if (!BUF_MEM_grow(dataB,1024))

                   { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }

         dataB->data[0]='\0';

         if (!nohead)

                   {

                   for (;;)

                            {

                            i=BIO_gets(bp,buf,254);

                            if (i <= 0) break;

 

                            while ((i >= 0) && (buf[i] <= ' ')) i--;

                            buf[++i]='\n'; buf[++i]='\0';

 

                            if (i != 65) end=1;

                            if (strncmp(buf,"-----END ",9) == 0)

                                     break;

                            if (i > 65) break;

                            if (!BUF_MEM_grow_clean(dataB,i+bl+9))

                                     {

                                     PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);

                                     goto err;

                                     }

                            memcpy(&(dataB->data[bl]),buf,i);

                            dataB->data[bl+i]='\0';

                            bl+=i;

                            if (end)

                                     {

                                     buf[0]='\0';

                                     i=BIO_gets(bp,buf,254);

                                     if (i <= 0) break;

 

                                     while ((i >= 0) && (buf[i] <= ' ')) i--;

                                     buf[++i]='\n'; buf[++i]='\0';

 

                                     break;

                                     }

                            }

                   }

         else

                   {

                   tmpB=headerB;

                   headerB=dataB;

                   dataB=tmpB;

                   bl=hl;

                   }

         i=strlen(nameB->data);

         if (     (strncmp(buf,"-----END ",9) != 0) ||

                   (strncmp(nameB->data,&(buf[9]),i) != 0) ||

                   (strncmp(&(buf[9+i]),"-----\n",6) != 0))

                   {

                   PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_END_LINE);

                   goto err;

                   }

 

         EVP_DecodeInit(&ctx);

         i=EVP_DecodeUpdate(&ctx,

                   (unsigned char *)dataB->data,&bl,

                   (unsigned char *)dataB->data,bl);

         if (i < 0)

                   {

                   PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE);

                   goto err;

                   }

         i=EVP_DecodeFinal(&ctx,(unsigned char *)&(dataB->data[bl]),&k);

         if (i < 0)

                   {

                   PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE);

                   goto err;

                   }

         bl+=k;

 

         if (bl == 0) goto err;

         *name=nameB->data;

         *header=headerB->data;

         *data=(unsigned char *)dataB->data;

         *len=bl;

         OPENSSL_free(nameB);

         OPENSSL_free(headerB);

         OPENSSL_free(dataB);

         return(1);

err:

         BUF_MEM_free(nameB);

         BUF_MEM_free(headerB);

         BUF_MEM_free(dataB);

         return(0);

         }

 

 

int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,

              long *len)

        {

        BIO *b;

        int ret;

 

        if ((b=BIO_new(BIO_s_file())) == NULL)

                   {

                   PEMerr(PEM_F_PEM_READ,ERR_R_BUF_LIB);

                return(0);

                   }

        BIO_set_fp(b,fp,BIO_NOCLOSE);

        ret=PEM_read_bio(b, name, header, data,len);

        BIO_free(b);

        return(ret);

        }

 

你可能感兴趣的:(一些有关PEM(PEM_read)的代码)