static int bio_zlib_write(BIO *b, const char *in, int inl) { BIO_ZLIB_CTX *ctx; int ret; z_stream *zout; if (!in || !inl) return 0; ctx = (BIO_ZLIB_CTX *) b->ptr; if (ctx->odone) return 0; zout = &ctx->zout; BIO_clear_retry_flags(b); if (!ctx->obuf) { ctx->obuf = OPENSSL_malloc(ctx->obufsize); /* Need error here */ if (!ctx->obuf) { COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE); return 0; } ctx->optr = ctx->obuf; ctx->ocount = 0; deflateInit(zout, ctx->comp_level); zout->next_out = ctx->obuf; zout->avail_out = ctx->obufsize; } /* Obtain input data directly from supplied buffer */ zout->next_in = (void *)in; zout->avail_in = inl; for (;;) { /* If data in output buffer write it first */ while (ctx->ocount) { ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); if (ret <= 0) { /* Total data written */ int tot = inl - zout->avail_in; BIO_copy_next_retry(b); if (ret < 0) return (tot > 0) ? tot : ret; return tot; } ctx->optr += ret; ctx->ocount -= ret; } /* Have we consumed all supplied data? */ if (!zout->avail_in) return inl; /* Compress some more */ /* Reset buffer */ ctx->optr = ctx->obuf; zout->next_out = ctx->obuf; zout->avail_out = ctx->obufsize; /* Compress some more */ ret = deflate(zout, 0); if (ret != Z_OK) { COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR); ERR_add_error_data(2, "zlib error:", zError(ret)); return 0; } ctx->ocount = ctx->obufsize - zout->avail_out; } }
static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret; int j, num = 0, r = -1; unsigned char *p; unsigned char *buf = NULL; BN_CTX *ctx = NULL; int local_blinding = 0; /* * Used only if the blinding structure is shared. A non-NULL unblind * instructs rsa_blinding_convert() and rsa_blinding_invert() to store * the unblinding factor outside the blinding structure. */ BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if ((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (f == NULL || ret == NULL || buf == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } /* * This check was for equality but PGP does evil things and chops off the * top '0' bytes */ if (flen > num) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN); goto err; } /* make data into a big number */ if (BN_bin2bn(from, (int)flen, f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) goto err; } /* do the decrypt */ if ((rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; } else { BIGNUM *d = NULL, *local_d = NULL; if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { local_d = d = BN_new(); if (d == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else { d = rsa->d; } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) { BN_free(local_d); goto err; } if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, rsa->_method_mod_n)) { BN_free(local_d); goto err; } /* We MUST free local_d before any further use of rsa->d */ BN_free(local_d); } if (blinding) if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; p = buf; j = BN_bn2bin(ret, p); /* j is only used with no-padding mode */ switch (padding) { case RSA_PKCS1_PADDING: r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num); break; case RSA_PKCS1_OAEP_PADDING: r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); break; case RSA_SSLV23_PADDING: r = RSA_padding_check_SSLv23(to, num, buf, j, num); break; case RSA_NO_PADDING: r = RSA_padding_check_none(to, num, buf, j, num); break; default: RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (r < 0) RSAerr(RSA_F_RSA_OSSL_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); err: if (ctx != NULL) BN_CTX_end(ctx); BN_CTX_free(ctx); OPENSSL_clear_free(buf, num); return (r); }
ASN1_STRING *d2i_ASN1_bytes (ASN1_STRING ** a, const unsigned char **pp, long length, int Ptag, int Pclass) { ASN1_STRING *ret = NULL; const unsigned char *p; unsigned char *s; long len; int inf, tag, xclass; int i = 0; if ((a == NULL) || ((*a) == NULL)) { if ((ret = ASN1_STRING_new ()) == NULL) return (NULL); } else ret = (*a); p = *pp; inf = ASN1_get_object (&p, &len, &tag, &xclass, length); if (inf & 0x80) { i = ASN1_R_BAD_OBJECT_HEADER; goto err; } if (tag != Ptag) { i = ASN1_R_WRONG_TAG; goto err; } if (inf & V_ASN1_CONSTRUCTED) { ASN1_const_CTX c; c.pp = pp; c.p = p; c.inf = inf; c.slen = len; c.tag = Ptag; c.xclass = Pclass; c.max = (length == 0) ? 0 : (p + length); if (!asn1_collate_primitive (ret, &c)) goto err; else { p = c.p; } } else { if (len != 0) { if ((ret->length < len) || (ret->data == NULL)) { if (ret->data != NULL) OPENSSL_free (ret->data); s = (unsigned char *) OPENSSL_malloc ((int) len + 1); if (s == NULL) { i = ERR_R_MALLOC_FAILURE; goto err; } } else s = ret->data; memcpy (s, p, (int) len); s[len] = '\0'; p += len; } else { s = NULL; if (ret->data != NULL) OPENSSL_free (ret->data); } ret->length = (int) len; ret->data = s; ret->type = Ptag; } if (a != NULL) (*a) = ret; *pp = p; return (ret); err: if ((ret != NULL) && ((a == NULL) || (*a != ret))) ASN1_STRING_free (ret); ASN1err (ASN1_F_D2I_ASN1_BYTES, i); return (NULL); }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; DH *dh=NULL; int i,badops=0,text=0; BIO *in=NULL,*out=NULL; int informat,outformat,check=0,noout=0,C=0,ret=1; char *infile,*outfile,*prog,*engine; apps_startup(); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; engine=NULL; infile=NULL; outfile=NULL; informat=FORMAT_PEM; outformat=FORMAT_PEM; prog=argv[0]; argc--; argv++; while (argc >= 1) { if (strcmp(*argv,"-inform") == 0) { if (--argc < 1) goto bad; informat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-outform") == 0) { if (--argc < 1) goto bad; outformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } else if (strcmp(*argv,"-check") == 0) check=1; else if (strcmp(*argv,"-text") == 0) text=1; else if (strcmp(*argv,"-C") == 0) C=1; else if (strcmp(*argv,"-noout") == 0) noout=1; else { BIO_printf(bio_err,"unknown option %s\n",*argv); badops=1; break; } argc--; argv++; } if (badops) { bad: BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog); BIO_printf(bio_err,"where options are\n"); BIO_printf(bio_err," -inform arg input format - one of DER PEM\n"); BIO_printf(bio_err," -outform arg output format - one of DER PEM\n"); BIO_printf(bio_err," -in arg input file\n"); BIO_printf(bio_err," -out arg output file\n"); BIO_printf(bio_err," -check check the DH parameters\n"); BIO_printf(bio_err," -text print a text form of the DH parameters\n"); BIO_printf(bio_err," -C Output C code\n"); BIO_printf(bio_err," -noout no output\n"); BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); goto end; } ERR_load_crypto_strings(); e = setup_engine(bio_err, engine, 0); in=BIO_new(BIO_s_file()); out=BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } if (infile == NULL) BIO_set_fp(in,stdin,BIO_NOCLOSE); else { if (BIO_read_filename(in,infile) <= 0) { perror(infile); goto end; } } if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outfile) <= 0) { perror(outfile); goto end; } } if (informat == FORMAT_ASN1) dh=d2i_DHparams_bio(in,NULL); else if (informat == FORMAT_PEM) dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL); else { BIO_printf(bio_err,"bad input format specified\n"); goto end; } if (dh == NULL) { BIO_printf(bio_err,"unable to load DH parameters\n"); ERR_print_errors(bio_err); goto end; } if (text) { DHparams_print(out,dh); #ifdef undef printf("p="); BN_print(stdout,dh->p); printf("\ng="); BN_print(stdout,dh->g); printf("\n"); if (dh->length != 0) printf("recommended private length=%ld\n",dh->length); #endif } if (check) { if (!DH_check(dh,&i)) { ERR_print_errors(bio_err); goto end; } if (i & DH_CHECK_P_NOT_PRIME) printf("p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) printf("p value is not a safe prime\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) printf("unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) printf("the g value is not a generator\n"); if (i == 0) printf("DH parameters appear to be ok.\n"); } if (C) { unsigned char *data; int len,l,bits; len=BN_num_bytes(dh->p); bits=BN_num_bits(dh->p); data=(unsigned char *)OPENSSL_malloc(len); if (data == NULL) { perror("OPENSSL_malloc"); goto end; } l=BN_bn2bin(dh->p,data); printf("static unsigned char dh%d_p[]={",bits); for (i=0; i<l; i++) { if ((i%12) == 0) printf("\n\t"); printf("0x%02X,",data[i]); } printf("\n\t};\n"); l=BN_bn2bin(dh->g,data); printf("static unsigned char dh%d_g[]={",bits); for (i=0; i<l; i++) { if ((i%12) == 0) printf("\n\t"); printf("0x%02X,",data[i]); } printf("\n\t};\n\n"); printf("DH *get_dh%d()\n\t{\n",bits); printf("\tDH *dh;\n\n"); printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n"); printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n", bits,bits); printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n", bits,bits); printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); printf("\t\treturn(NULL);\n"); printf("\treturn(dh);\n\t}\n"); OPENSSL_free(data); } if (!noout) { if (outformat == FORMAT_ASN1) i=i2d_DHparams_bio(out,dh); else if (outformat == FORMAT_PEM) i=PEM_write_bio_DHparams(out,dh); else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err,"unable to write DH parameters\n"); ERR_print_errors(bio_err); goto end; } } ret=0; end: if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); if (dh != NULL) DH_free(dh); apps_shutdown(); OPENSSL_EXIT(ret); }
static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret; int i, j, k, num = 0, r = -1; unsigned char *buf = NULL; BN_CTX *ctx = NULL; if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); return -1; } if (BN_ucmp(rsa->n, rsa->e) <= 0) { RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); return -1; } /* for large moduli, enforce exponent limit */ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); return -1; } } if ((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (f == NULL || ret == NULL || buf == NULL) { RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } switch (padding) { case RSA_PKCS1_PADDING: i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen); break; case RSA_PKCS1_OAEP_PADDING: i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); break; case RSA_SSLV23_PADDING: i = RSA_padding_add_SSLv23(buf, num, from, flen); break; case RSA_NO_PADDING: i = RSA_padding_add_none(buf, num, from, flen); break; default: RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (i <= 0) goto err; if (BN_bin2bn(buf, num, f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { /* usually the padding functions would catch this */ RSAerr(RSA_F_RSA_OSSL_PUBLIC_ENCRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) goto err; if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, rsa->_method_mod_n)) goto err; /* * put in leading 0 bytes if the number is less than the length of the * modulus */ j = BN_num_bytes(ret); i = BN_bn2bin(ret, &(to[num - j])); for (k = 0; k < (num - i); k++) to[k] = 0; r = num; err: if (ctx != NULL) BN_CTX_end(ctx); BN_CTX_free(ctx); OPENSSL_clear_free(buf, num); return (r); }
int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, unsigned char *sigbuf, unsigned int siglen, RSA *rsa) { int i,ret=0,sigtype; unsigned char *s; X509_SIG *sig=NULL; if (siglen != (unsigned int)RSA_size(rsa)) { RSAerr(RSA_F_RSA_VERIFY,RSA_R_WRONG_SIGNATURE_LENGTH); return(0); } if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) { return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, rsa); } s=(unsigned char *)OPENSSL_malloc((unsigned int)siglen); if (s == NULL) { RSAerr(RSA_F_RSA_VERIFY,ERR_R_MALLOC_FAILURE); goto err; } if(dtype == NID_md5_sha1) { if (m_len != SSL_SIG_LENGTH) { RSAerr(RSA_F_RSA_VERIFY,RSA_R_INVALID_MESSAGE_LENGTH); goto err; } } i=RSA_public_decrypt((int)siglen,sigbuf,s,rsa,RSA_PKCS1_PADDING); if (i <= 0) goto err; /* Special case: SSL signature */ if(dtype == NID_md5_sha1) { if((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); else ret = 1; } else { const unsigned char *p=s; sig=d2i_X509_SIG(NULL,&p,(long)i); if (sig == NULL) goto err; /* Excess data can be used to create forgeries */ if(p != s+i) { RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); goto err; } /* Parameters to the signature algorithm can also be used to create forgeries */ if(sig->algor->parameter && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); goto err; } sigtype=OBJ_obj2nid(sig->algor->algorithm); #ifdef RSA_DEBUG /* put a backward compatibility flag in EAY */ fprintf(stderr,"in(%s) expect(%s)\n",OBJ_nid2ln(sigtype), OBJ_nid2ln(dtype)); #endif if (sigtype != dtype) { if (((dtype == NID_md5) && (sigtype == NID_md5WithRSAEncryption)) || ((dtype == NID_md2) && (sigtype == NID_md2WithRSAEncryption))) { /* ok, we will let it through */ #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) fprintf(stderr,"signature has problems, re-make with post SSLeay045\n"); #endif } else { RSAerr(RSA_F_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); goto err; } } if ( ((unsigned int)sig->digest->length != m_len) || (memcmp(m,sig->digest->data,m_len) != 0)) { RSAerr(RSA_F_RSA_VERIFY,RSA_R_BAD_SIGNATURE); } else ret=1; } err: if (sig != NULL) X509_SIG_free(sig); if (s != NULL) { OPENSSL_cleanse(s,(unsigned int)siglen); OPENSSL_free(s); } return(ret); }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int ret=1; RSA *rsa=NULL; int i,badops=0, sgckey=0; const EVP_CIPHER *enc=NULL; BIO *out=NULL; int informat,outformat,text=0,check=0,noout=0; int pubin = 0, pubout = 0; char *infile,*outfile,*prog; char *passargin = NULL, *passargout = NULL; char *passin = NULL, *passout = NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif int modulus=0; int pvk_encr = 2; apps_startup(); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; infile=NULL; outfile=NULL; informat=FORMAT_PEM; outformat=FORMAT_PEM; prog=argv[0]; argc--; argv++; while (argc >= 1) { if (strcmp(*argv,"-inform") == 0) { if (--argc < 1) goto bad; informat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-outform") == 0) { if (--argc < 1) goto bad; outformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } else if (strcmp(*argv,"-passin") == 0) { if (--argc < 1) goto bad; passargin= *(++argv); } else if (strcmp(*argv,"-passout") == 0) { if (--argc < 1) goto bad; passargout= *(++argv); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } #endif else if (strcmp(*argv,"-sgckey") == 0) sgckey=1; else if (strcmp(*argv,"-pubin") == 0) pubin=1; else if (strcmp(*argv,"-pubout") == 0) pubout=1; else if (strcmp(*argv,"-RSAPublicKey_in") == 0) pubin = 2; else if (strcmp(*argv,"-RSAPublicKey_out") == 0) pubout = 2; else if (strcmp(*argv,"-pvk-strong") == 0) pvk_encr=2; else if (strcmp(*argv,"-pvk-weak") == 0) pvk_encr=1; else if (strcmp(*argv,"-pvk-none") == 0) pvk_encr=0; else if (strcmp(*argv,"-noout") == 0) noout=1; else if (strcmp(*argv,"-text") == 0) text=1; else if (strcmp(*argv,"-modulus") == 0) modulus=1; else if (strcmp(*argv,"-check") == 0) check=1; else if ((enc=EVP_get_cipherbyname(&(argv[0][1]))) == NULL) { BIO_printf(bio_err,"unknown option %s\n",*argv); badops=1; break; } argc--; argv++; } if (badops) { bad: BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog); BIO_printf(bio_err,"where options are\n"); BIO_printf(bio_err," -inform arg input format - one of DER NET PEM\n"); BIO_printf(bio_err," -outform arg output format - one of DER NET PEM\n"); BIO_printf(bio_err," -in arg input file\n"); BIO_printf(bio_err," -sgckey Use IIS SGC key format\n"); BIO_printf(bio_err," -passin arg input file pass phrase source\n"); BIO_printf(bio_err," -out arg output file\n"); BIO_printf(bio_err," -passout arg output file pass phrase source\n"); BIO_printf(bio_err," -des encrypt PEM output with cbc des\n"); BIO_printf(bio_err," -des3 encrypt PEM output with ede cbc des using 168 bit key\n"); #ifndef OPENSSL_NO_IDEA BIO_printf(bio_err," -idea encrypt PEM output with cbc idea\n"); #endif #ifndef OPENSSL_NO_SEED BIO_printf(bio_err," -seed encrypt PEM output with cbc seed\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf(bio_err," -aes128, -aes192, -aes256\n"); BIO_printf(bio_err," encrypt PEM output with cbc aes\n"); #endif #ifndef OPENSSL_NO_CAMELLIA BIO_printf(bio_err," -camellia128, -camellia192, -camellia256\n"); BIO_printf(bio_err," encrypt PEM output with cbc camellia\n"); #endif BIO_printf(bio_err," -text print the key in text\n"); BIO_printf(bio_err," -noout don't print key out\n"); BIO_printf(bio_err," -modulus print the RSA key modulus\n"); BIO_printf(bio_err," -check verify key consistency\n"); BIO_printf(bio_err," -pubin expect a public key in input file\n"); BIO_printf(bio_err," -pubout output a public key\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); #endif goto end; } ERR_load_crypto_strings(); #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if(!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); goto end; } if(check && pubin) { BIO_printf(bio_err, "Only private keys can be checked\n"); goto end; } out=BIO_new(BIO_s_file()); { EVP_PKEY *pkey; if (pubin) { int tmpformat=-1; if (pubin == 2) { if (informat == FORMAT_PEM) tmpformat = FORMAT_PEMRSA; else if (informat == FORMAT_ASN1) tmpformat = FORMAT_ASN1RSA; } else if (informat == FORMAT_NETSCAPE && sgckey) tmpformat = FORMAT_IISSGC; else tmpformat = informat; pkey = load_pubkey(bio_err, infile, tmpformat, 1, passin, e, "Public Key"); } else pkey = load_key(bio_err, infile, (informat == FORMAT_NETSCAPE && sgckey ? FORMAT_IISSGC : informat), 1, passin, e, "Private Key"); if (pkey != NULL) rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); } if (rsa == NULL) { ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outfile) <= 0) { perror(outfile); goto end; } } if (text) if (!RSA_print(out,rsa,0)) { perror(outfile); ERR_print_errors(bio_err); goto end; } if (modulus) { BIO_printf(out,"Modulus="); BN_print(out,rsa->n); BIO_printf(out,"\n"); } if (check) { int r = RSA_check_key(rsa); if (r == 1) BIO_printf(out,"RSA key ok\n"); else if (r == 0) { unsigned long err; while ((err = ERR_peek_error()) != 0 && ERR_GET_LIB(err) == ERR_LIB_RSA && ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY && ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) { BIO_printf(out, "RSA key error: %s\n", ERR_reason_error_string(err)); ERR_get_error(); /* remove e from error stack */ } } if (r == -1 || ERR_peek_error() != 0) /* should happen only if r == -1 */ { ERR_print_errors(bio_err); goto end; } } if (noout) { ret = 0; goto end; } BIO_printf(bio_err,"writing RSA key\n"); if (outformat == FORMAT_ASN1) { if(pubout || pubin) { if (pubout == 2) i=i2d_RSAPublicKey_bio(out,rsa); else i=i2d_RSA_PUBKEY_bio(out,rsa); } else i=i2d_RSAPrivateKey_bio(out,rsa); } #ifndef OPENSSL_NO_RC4 else if (outformat == FORMAT_NETSCAPE) { unsigned char *p,*pp; int size; i=1; size=i2d_RSA_NET(rsa,NULL,NULL, sgckey); if ((p=(unsigned char *)OPENSSL_malloc(size)) == NULL) { BIO_printf(bio_err,"Memory allocation failure\n"); goto end; } pp=p; i2d_RSA_NET(rsa,&p,NULL, sgckey); BIO_write(out,(char *)pp,size); OPENSSL_free(pp); } #endif else if (outformat == FORMAT_PEM) { if(pubout || pubin) { if (pubout == 2) i=PEM_write_bio_RSAPublicKey(out,rsa); else i=PEM_write_bio_RSA_PUBKEY(out,rsa); } else i=PEM_write_bio_RSAPrivateKey(out,rsa, enc,NULL,0,NULL,passout); #ifndef OPENSSL_NO_DSA } else if (outformat == FORMAT_MSBLOB || outformat == FORMAT_PVK) { EVP_PKEY *pk; pk = EVP_PKEY_new(); EVP_PKEY_set1_RSA(pk, rsa); if (outformat == FORMAT_PVK) i = i2b_PVK_bio(out, pk, pvk_encr, 0, passout); else if (pubin || pubout) i = i2b_PublicKey_bio(out, pk); else i = i2b_PrivateKey_bio(out, pk); EVP_PKEY_free(pk); #endif } else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } if (i <= 0) { BIO_printf(bio_err,"unable to write key\n"); ERR_print_errors(bio_err); } else ret=0; end: if(out != NULL) BIO_free_all(out); if(rsa != NULL) RSA_free(rsa); if(passin) OPENSSL_free(passin); if(passout) OPENSSL_free(passout); apps_shutdown(); OPENSSL_EXIT(ret); }
static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) { CMS_EncryptedContentInfo *ec; CMS_KEKRecipientInfo *kekri; AES_KEY actx; unsigned char *ukey = NULL; int ukeylen; int r = 0, wrap_nid; ec = cms->d.envelopedData->encryptedContentInfo; kekri = ri->d.kekri; if (!kekri->key) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY); return 0; } wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm); if (aes_wrap_keylen(wrap_nid) != kekri->keylen) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_INVALID_KEY_LENGTH); return 0; } /* If encrypted key length is invalid don't bother */ if (kekri->encryptedKey->length < 16) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); goto err; } if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_ERROR_SETTING_KEY); goto err; } ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); if (ukey == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } ukeylen = AES_unwrap_key(&actx, NULL, ukey, kekri->encryptedKey->data, kekri->encryptedKey->length); if (ukeylen <= 0) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR); goto err; } ec->key = ukey; ec->keylen = ukeylen; r = 1; err: if (!r) OPENSSL_free(ukey); OPENSSL_cleanse(&actx, sizeof(actx)); return r; }
TXT_DB *TXT_DB_read(BIO *in, int num) { TXT_DB *ret=NULL; int er=1; int esc=0; long ln=0; int i,add,n; int size=BUFSIZE; int offset=0; char *p,**pp,*f; BUF_MEM *buf=NULL; if ((buf=BUF_MEM_new()) == NULL) goto err; if (!BUF_MEM_grow(buf,size)) goto err; if ((ret=(TXT_DB *)OPENSSL_malloc(sizeof(TXT_DB))) == NULL) goto err; ret->num_fields=num; ret->index=NULL; ret->qual=NULL; if ((ret->data=sk_new_null()) == NULL) goto err; if ((ret->index=(LHASH **)OPENSSL_malloc(sizeof(LHASH *)*num)) == NULL) goto err; if ((ret->qual=(int (**)(char **))OPENSSL_malloc(sizeof(int (**)(char **))*num)) == NULL) goto err; for (i=0; i<num; i++) { ret->index[i]=NULL; ret->qual[i]=NULL; } add=(num+1)*sizeof(char *); buf->data[size-1]='\0'; offset=0; for (;;) { if (offset != 0) { size+=BUFSIZE; if (!BUF_MEM_grow_clean(buf,size)) goto err; } buf->data[offset]='\0'; BIO_gets(in,&(buf->data[offset]),size-offset); ln++; if (buf->data[offset] == '\0') break; if ((offset == 0) && (buf->data[0] == '#')) continue; i=strlen(&(buf->data[offset])); offset+=i; if (buf->data[offset-1] != '\n') continue; else { buf->data[offset-1]='\0'; /* blat the '\n' */ if (!(p=(char *)OPENSSL_malloc(add+offset))) goto err; offset=0; } pp=(char **)p; p+=add; n=0; pp[n++]=p; i=0; f=buf->data; esc=0; for (;;) { if (*f == '\0') break; if (*f == '\t') { if (esc) p--; else { *(p++)='\0'; f++; if (n >= num) break; pp[n++]=p; continue; } } esc=(*f == '\\'); *(p++)= *(f++); } *(p++)='\0'; if ((n != num) || (*f != '\0')) { #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporaty fix :-( */ //fprintf(stderr,"wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",ln,num,n,f); #endif er=2; goto err; } pp[n]=p; if (!sk_push(ret->data,(char *)pp)) { #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporaty fix :-( */ // fprintf(stderr,"failure in sk_push\n"); #endif er=2; goto err; } } er=0; err: BUF_MEM_free(buf); if (er) { #if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) // if (er == 1) fprintf(stderr,"OPENSSL_malloc failure\n"); #endif if (ret != NULL) { if (ret->data != NULL) sk_free(ret->data); if (ret->index != NULL) OPENSSL_free(ret->index); if (ret->qual != NULL) OPENSSL_free(ret->qual); if (ret != NULL) OPENSSL_free(ret); } return(NULL); } else return(ret); }
static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) { CMS_KeyTransRecipientInfo *ktri; CMS_EncryptedContentInfo *ec; EVP_PKEY_CTX *pctx; unsigned char *ek = NULL; size_t eklen; int ret = 0; if (ri->type != CMS_RECIPINFO_TRANS) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT); return 0; } ktri = ri->d.ktri; ec = cms->d.envelopedData->encryptedContentInfo; pctx = ktri->pctx; if (pctx) { if (!cms_env_asn1_ctrl(ri, 0)) goto err; } else { pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); if (pctx == NULL) return 0; if (EVP_PKEY_encrypt_init(pctx) <= 0) goto err; } if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR); goto err; } if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) goto err; ek = OPENSSL_malloc(eklen); if (ek == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) goto err; ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); ek = NULL; ret = 1; err: EVP_PKEY_CTX_free(pctx); ktri->pctx = NULL; OPENSSL_free(ek); return ret; }
static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) { CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; EVP_PKEY *pkey = ktri->pkey; unsigned char *ek = NULL; size_t eklen; int ret = 0; CMS_EncryptedContentInfo *ec; ec = cms->d.envelopedData->encryptedContentInfo; if (ktri->pkey == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY); return 0; } ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL); if (ktri->pctx == NULL) return 0; if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) goto err; if (!cms_env_asn1_ctrl(ri, 1)) goto err; if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT, EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR); goto err; } if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen, ktri->encryptedKey->data, ktri->encryptedKey->length) <= 0) goto err; ek = OPENSSL_malloc(eklen); if (ek == NULL) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen, ktri->encryptedKey->data, ktri->encryptedKey->length) <= 0) { CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); goto err; } ret = 1; OPENSSL_clear_free(ec->key, ec->keylen); ec->key = ek; ec->keylen = eklen; err: EVP_PKEY_CTX_free(ktri->pctx); ktri->pctx = NULL; if (!ret) OPENSSL_free(ek); return ret; }
static int do_dh_print(BIO *bp, const DH *x, int indent, ASN1_PCTX *ctx, int ptype) { unsigned char *m = NULL; int reason = ERR_R_BUF_LIB; size_t buf_len = 0; const char *ktype = NULL; BIGNUM *priv_key, *pub_key; if (ptype == 2) priv_key = x->priv_key; else priv_key = NULL; if (ptype > 0) pub_key = x->pub_key; else pub_key = NULL; update_buflen(x->p, &buf_len); if (buf_len == 0) { reason = ERR_R_PASSED_NULL_PARAMETER; goto err; } update_buflen(x->g, &buf_len); update_buflen(x->q, &buf_len); update_buflen(x->j, &buf_len); update_buflen(x->counter, &buf_len); update_buflen(pub_key, &buf_len); update_buflen(priv_key, &buf_len); if (ptype == 2) ktype = "DH Private-Key"; else if (ptype == 1) ktype = "DH Public-Key"; else ktype = "DH Parameters"; m = OPENSSL_malloc(buf_len + 10); if (m == NULL) { reason = ERR_R_MALLOC_FAILURE; goto err; } BIO_indent(bp, indent, 128); if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) goto err; indent += 4; if (!ASN1_bn_print(bp, "private-key:", priv_key, m, indent)) goto err; if (!ASN1_bn_print(bp, "public-key:", pub_key, m, indent)) goto err; if (!ASN1_bn_print(bp, "prime:", x->p, m, indent)) goto err; if (!ASN1_bn_print(bp, "generator:", x->g, m, indent)) goto err; if (x->q && !ASN1_bn_print(bp, "subgroup order:", x->q, m, indent)) goto err; if (x->j && !ASN1_bn_print(bp, "subgroup factor:", x->j, m, indent)) goto err; if (x->seed) { int i; BIO_indent(bp, indent, 128); BIO_puts(bp, "seed:"); for (i = 0; i < x->seedlen; i++) { if ((i % 15) == 0) { if (BIO_puts(bp, "\n") <= 0 || !BIO_indent(bp, indent + 4, 128)) goto err; } if (BIO_printf(bp, "%02x%s", x->seed[i], ((i + 1) == x->seedlen) ? "" : ":") <= 0) goto err; } if (BIO_write(bp, "\n", 1) <= 0) return (0); } if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, m, indent)) goto err; if (x->length != 0) { BIO_indent(bp, indent, 128); if (BIO_printf(bp, "recommended-private-length: %d bits\n", (int)x->length) <= 0) goto err; } OPENSSL_free(m); return 1; err: DHerr(DH_F_DO_DH_PRINT, reason); OPENSSL_free(m); return 0; }
static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) { BIO *dbio; BIO_F_BUFFER_CTX *ctx; long ret=1; char *p1,*p2; int r,i,*ip; int ibs,obs; ctx=(BIO_F_BUFFER_CTX *)b->ptr; switch (cmd) { case BIO_CTRL_RESET: ctx->ibuf_off=0; ctx->ibuf_len=0; ctx->obuf_off=0; ctx->obuf_len=0; if (b->next_bio == NULL) return(0); ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_CTRL_INFO: ret=(long)ctx->obuf_len; break; case BIO_C_GET_BUFF_NUM_LINES: ret=0; p1=ctx->ibuf; for (i=ctx->ibuf_off; i<ctx->ibuf_len; i++) { if (p1[i] == '\n') ret++; } break; case BIO_CTRL_WPENDING: ret=(long)ctx->obuf_len; if (ret == 0) { if (b->next_bio == NULL) return(0); ret=BIO_ctrl(b->next_bio,cmd,num,ptr); } break; case BIO_CTRL_PENDING: ret=(long)ctx->ibuf_len; if (ret == 0) { if (b->next_bio == NULL) return(0); ret=BIO_ctrl(b->next_bio,cmd,num,ptr); } break; case BIO_C_SET_BUFF_READ_DATA: if (num > ctx->ibuf_size) { p1=OPENSSL_malloc((int)num); if (p1 == NULL) goto malloc_error; if (ctx->ibuf != NULL) OPENSSL_free(ctx->ibuf); ctx->ibuf=p1; } ctx->ibuf_off=0; ctx->ibuf_len=(int)num; memcpy(ctx->ibuf,ptr,(int)num); ret=1; break; case BIO_C_SET_BUFF_SIZE: if (ptr != NULL) { ip=(int *)ptr; if (*ip == 0) { ibs=(int)num; obs=ctx->obuf_size; } else /* if (*ip == 1) */ { ibs=ctx->ibuf_size; obs=(int)num; } } else { ibs=(int)num; obs=(int)num; } p1=ctx->ibuf; p2=ctx->obuf; if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) { p1=(char *)OPENSSL_malloc((int)num); if (p1 == NULL) goto malloc_error; } if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) { p2=(char *)OPENSSL_malloc((int)num); if (p2 == NULL) { if (p1 != ctx->ibuf) OPENSSL_free(p1); goto malloc_error; } } if (ctx->ibuf != p1) { OPENSSL_free(ctx->ibuf); ctx->ibuf=p1; ctx->ibuf_off=0; ctx->ibuf_len=0; ctx->ibuf_size=ibs; } if (ctx->obuf != p2) { OPENSSL_free(ctx->obuf); ctx->obuf=p2; ctx->obuf_off=0; ctx->obuf_len=0; ctx->obuf_size=obs; } break; case BIO_C_DO_STATE_MACHINE: if (b->next_bio == NULL) return(0); BIO_clear_retry_flags(b); ret=BIO_ctrl(b->next_bio,cmd,num,ptr); BIO_copy_next_retry(b); break; case BIO_CTRL_FLUSH: if (b->next_bio == NULL) return(0); if (ctx->obuf_len <= 0) { ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; } for (;;) { BIO_clear_retry_flags(b); if (ctx->obuf_len > ctx->obuf_off) { r=BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len-ctx->obuf_off); #if 0 fprintf(stderr,"FLUSH [%3d] %3d -> %3d\n",ctx->obuf_off,ctx->obuf_len-ctx->obuf_off,r); #endif BIO_copy_next_retry(b); if (r <= 0) return((long)r); ctx->obuf_off+=r; } else { ctx->obuf_len=0; ctx->obuf_off=0; ret=1; break; } } ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; case BIO_CTRL_DUP: dbio=(BIO *)ptr; if ( !BIO_set_read_buffer_size(dbio,ctx->ibuf_size) || !BIO_set_write_buffer_size(dbio,ctx->obuf_size)) ret=0; break; default: if (b->next_bio == NULL) return(0); ret=BIO_ctrl(b->next_bio,cmd,num,ptr); break; } return(ret); malloc_error: BIOerr(BIO_F_BUFFER_CTRL,ERR_R_MALLOC_FAILURE); return(0); }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; BIO *in = NULL, *out = NULL; char *infile = NULL, *outfile = NULL; #ifndef OPENSSL_NO_ENGINE char *engine = NULL; #endif char *keyfile = NULL; char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY; int keyform = FORMAT_PEM; char need_priv = 0, badarg = 0, rev = 0; char hexdump = 0, asn1parse = 0; X509 *x; EVP_PKEY *pkey = NULL; RSA *rsa = NULL; unsigned char *rsa_in = NULL, *rsa_out = NULL, pad; char *passargin = NULL, *passin = NULL; int rsa_inlen, rsa_outlen = 0; int keysize; int ret = 1; argc--; argv++; if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); if (!load_config(bio_err, NULL)) goto end; ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); pad = RSA_PKCS1_PADDING; while(argc >= 1) { if (!strcmp(*argv,"-in")) { if (--argc < 1) badarg = 1; else infile= *(++argv); } else if (!strcmp(*argv,"-out")) { if (--argc < 1) badarg = 1; else outfile= *(++argv); } else if(!strcmp(*argv, "-inkey")) { if (--argc < 1) badarg = 1; else keyfile = *(++argv); } else if (!strcmp(*argv,"-passin")) { if (--argc < 1) badarg = 1; else passargin= *(++argv); } else if (strcmp(*argv,"-keyform") == 0) { if (--argc < 1) badarg = 1; else keyform=str2fmt(*(++argv)); #ifndef OPENSSL_NO_ENGINE } else if(!strcmp(*argv, "-engine")) { if (--argc < 1) badarg = 1; else engine = *(++argv); #endif } else if(!strcmp(*argv, "-pubin")) { key_type = KEY_PUBKEY; } else if(!strcmp(*argv, "-certin")) { key_type = KEY_CERT; } else if(!strcmp(*argv, "-asn1parse")) asn1parse = 1; else if(!strcmp(*argv, "-hexdump")) hexdump = 1; else if(!strcmp(*argv, "-raw")) pad = RSA_NO_PADDING; else if(!strcmp(*argv, "-oaep")) pad = RSA_PKCS1_OAEP_PADDING; else if(!strcmp(*argv, "-ssl")) pad = RSA_SSLV23_PADDING; else if(!strcmp(*argv, "-pkcs")) pad = RSA_PKCS1_PADDING; else if(!strcmp(*argv, "-x931")) pad = RSA_X931_PADDING; else if(!strcmp(*argv, "-sign")) { rsa_mode = RSA_SIGN; need_priv = 1; } else if(!strcmp(*argv, "-verify")) rsa_mode = RSA_VERIFY; else if(!strcmp(*argv, "-rev")) rev = 1; else if(!strcmp(*argv, "-encrypt")) rsa_mode = RSA_ENCRYPT; else if(!strcmp(*argv, "-decrypt")) { rsa_mode = RSA_DECRYPT; need_priv = 1; } else badarg = 1; if(badarg) { usage(); goto end; } argc--; argv++; } if(need_priv && (key_type != KEY_PRIVKEY)) { BIO_printf(bio_err, "A private key is needed for this operation\n"); goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } /* FIXME: seed PRNG only if needed */ app_RAND_load_file(NULL, bio_err, 0); switch(key_type) { case KEY_PRIVKEY: pkey = load_key(bio_err, keyfile, keyform, 0, passin, e, "Private Key"); break; case KEY_PUBKEY: pkey = load_pubkey(bio_err, keyfile, keyform, 0, NULL, e, "Public Key"); break; case KEY_CERT: x = load_cert(bio_err, keyfile, keyform, NULL, e, "Certificate"); if(x) { pkey = X509_get_pubkey(x); X509_free(x); } break; } if(!pkey) { return 1; } rsa = EVP_PKEY_get1_RSA(pkey); EVP_PKEY_free(pkey); if(!rsa) { BIO_printf(bio_err, "Error getting RSA key\n"); ERR_print_errors(bio_err); goto end; } if(infile) { if(!(in = BIO_new_file(infile, "rb"))) { BIO_printf(bio_err, "Error Reading Input File\n"); ERR_print_errors(bio_err); goto end; } } else in = BIO_new_fp(stdin, BIO_NOCLOSE); if(outfile) { if(!(out = BIO_new_file(outfile, "wb"))) { BIO_printf(bio_err, "Error Reading Output File\n"); ERR_print_errors(bio_err); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } keysize = RSA_size(rsa); rsa_in = OPENSSL_malloc(keysize * 2); rsa_out = OPENSSL_malloc(keysize); /* Read the input data */ rsa_inlen = BIO_read(in, rsa_in, keysize * 2); if(rsa_inlen <= 0) { BIO_printf(bio_err, "Error reading input Data\n"); exit(1); } if(rev) { int i; unsigned char ctmp; for(i = 0; i < rsa_inlen/2; i++) { ctmp = rsa_in[i]; rsa_in[i] = rsa_in[rsa_inlen - 1 - i]; rsa_in[rsa_inlen - 1 - i] = ctmp; } } switch(rsa_mode) { case RSA_VERIFY: rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); break; case RSA_SIGN: rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); break; case RSA_ENCRYPT: rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); break; case RSA_DECRYPT: rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad); break; } if(rsa_outlen <= 0) { BIO_printf(bio_err, "RSA operation error\n"); ERR_print_errors(bio_err); goto end; } ret = 0; if(asn1parse) { if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) { ERR_print_errors(bio_err); } } else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen); else BIO_write(out, rsa_out, rsa_outlen); end: RSA_free(rsa); BIO_free(in); BIO_free_all(out); if(rsa_in) OPENSSL_free(rsa_in); if(rsa_out) OPENSSL_free(rsa_out); if(passin) OPENSSL_free(passin); return ret; }
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, int prf_nid, int keylen) { X509_ALGOR *keyfunc = NULL; PBKDF2PARAM *kdf = NULL; ASN1_OCTET_STRING *osalt = NULL; if ((kdf = PBKDF2PARAM_new()) == NULL) goto merr; if ((osalt = ASN1_OCTET_STRING_new()) == NULL) goto merr; kdf->salt->value.octet_string = osalt; kdf->salt->type = V_ASN1_OCTET_STRING; if (saltlen == 0) saltlen = PKCS5_SALT_LEN; if ((osalt->data = OPENSSL_malloc(saltlen)) == NULL) goto merr; osalt->length = saltlen; if (salt) memcpy(osalt->data, salt, saltlen); else if (RAND_bytes(osalt->data, saltlen) <= 0) goto merr; if (iter <= 0) iter = PKCS5_DEFAULT_ITER; if (!ASN1_INTEGER_set(kdf->iter, iter)) goto merr; /* If have a key len set it up */ if (keylen > 0) { if ((kdf->keylength = ASN1_INTEGER_new()) == NULL) goto merr; if (!ASN1_INTEGER_set(kdf->keylength, keylen)) goto merr; } /* prf can stay NULL if we are using hmacWithSHA1 */ if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) { kdf->prf = X509_ALGOR_new(); if (kdf->prf == NULL) goto merr; X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL); } /* Finally setup the keyfunc structure */ keyfunc = X509_ALGOR_new(); if (keyfunc == NULL) goto merr; keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2); /* Encode PBKDF2PARAM into parameter of pbe2 */ if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), kdf, &keyfunc->parameter)) goto merr; PBKDF2PARAM_free(kdf); return keyfunc; merr: ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE); PBKDF2PARAM_free(kdf); X509_ALGOR_free(keyfunc); return NULL; }
static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) { unsigned char *m = NULL; int ret = 0; size_t buf_len = 0; const char *ktype = NULL; const BIGNUM *priv_key, *pub_key; if (ptype == 2) priv_key = x->priv_key; else priv_key = NULL; if (ptype > 0) pub_key = x->pub_key; else pub_key = NULL; if (ptype == 2) ktype = "Private-Key"; else if (ptype == 1) ktype = "Public-Key"; else ktype = "DSA-Parameters"; update_buflen(x->p, &buf_len); update_buflen(x->q, &buf_len); update_buflen(x->g, &buf_len); update_buflen(priv_key, &buf_len); update_buflen(pub_key, &buf_len); m = (unsigned char *)OPENSSL_malloc(buf_len + 10); if (m == NULL) { DSAerr(DSA_F_DO_DSA_PRINT, ERR_R_MALLOC_FAILURE); goto err; } if (priv_key) { if (!BIO_indent(bp, off, 128)) goto err; if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) goto err; } if (!ASN1_bn_print(bp, "priv:", priv_key, m, off)) goto err; if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off)) goto err; if (!ASN1_bn_print(bp, "P: ", x->p, m, off)) goto err; if (!ASN1_bn_print(bp, "Q: ", x->q, m, off)) goto err; if (!ASN1_bn_print(bp, "G: ", x->g, m, off)) goto err; ret = 1; err: if (m != NULL) OPENSSL_free(m); return (ret); }
int MAIN(int argc, char **argv) { #ifndef OPENSSL_NO_ENGINE ENGINE *e = NULL; #endif DH *dh=NULL; int i,badops=0,text=0; #ifndef OPENSSL_NO_DSA int dsaparam=0; #endif BIO *in=NULL,*out=NULL; int informat,outformat,check=0,noout=0,C=0,ret=1; char *infile,*outfile,*prog; char *inrand=NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif int num = 0, g = 0; apps_startup(); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; infile=NULL; outfile=NULL; informat=FORMAT_PEM; outformat=FORMAT_PEM; prog=argv[0]; argc--; argv++; while (argc >= 1) { if (strcmp(*argv,"-inform") == 0) { if (--argc < 1) goto bad; informat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-outform") == 0) { if (--argc < 1) goto bad; outformat=str2fmt(*(++argv)); } else if (strcmp(*argv,"-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (strcmp(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } #ifndef OPENSSL_NO_ENGINE else if (strcmp(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } #endif else if (strcmp(*argv,"-check") == 0) check=1; else if (strcmp(*argv,"-text") == 0) text=1; #ifndef OPENSSL_NO_DSA else if (strcmp(*argv,"-dsaparam") == 0) dsaparam=1; #endif else if (strcmp(*argv,"-C") == 0) C=1; else if (strcmp(*argv,"-noout") == 0) noout=1; else if (strcmp(*argv,"-2") == 0) g=2; else if (strcmp(*argv,"-5") == 0) g=5; else if (strcmp(*argv,"-rand") == 0) { if (--argc < 1) goto bad; inrand= *(++argv); } else if (((sscanf(*argv,"%d",&num) == 0) || (num <= 0))) goto bad; argv++; argc--; } if (badops) { bad: BIO_printf(bio_err,"%s [options] [numbits]\n",prog); BIO_printf(bio_err,"where options are\n"); BIO_printf(bio_err," -inform arg input format - one of DER PEM\n"); BIO_printf(bio_err," -outform arg output format - one of DER PEM\n"); BIO_printf(bio_err," -in arg input file\n"); BIO_printf(bio_err," -out arg output file\n"); #ifndef OPENSSL_NO_DSA BIO_printf(bio_err," -dsaparam read or generate DSA parameters, convert to DH\n"); #endif BIO_printf(bio_err," -check check the DH parameters\n"); BIO_printf(bio_err," -text print a text form of the DH parameters\n"); BIO_printf(bio_err," -C Output C code\n"); BIO_printf(bio_err," -2 generate parameters using 2 as the generator value\n"); BIO_printf(bio_err," -5 generate parameters using 5 as the generator value\n"); BIO_printf(bio_err," numbits number of bits in to generate (default 512)\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err," - load the file (or the files in the directory) into\n"); BIO_printf(bio_err," the random number generator\n"); BIO_printf(bio_err," -noout no output\n"); goto end; } ERR_load_crypto_strings(); #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (g && !num) num = DEFBITS; #ifndef OPENSSL_NO_DSA if (dsaparam) { if (g) { BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n"); goto end; } } else #endif { /* DH parameters */ if (num && !g) g = 2; } if(num) { BN_GENCB cb; BN_GENCB_set(&cb, dh_cb, bio_err); if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL) { BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n"); } if (inrand != NULL) BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); #ifndef OPENSSL_NO_DSA if (dsaparam) { DSA *dsa = DSA_new(); BIO_printf(bio_err,"Generating DSA parameters, %d bit long prime\n",num); if(!dsa || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL, &cb)) { if(dsa) DSA_free(dsa); ERR_print_errors(bio_err); goto end; } dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { ERR_print_errors(bio_err); goto end; } } else #endif { dh = DH_new(); BIO_printf(bio_err,"Generating DH parameters, %d bit long safe prime, generator %d\n",num,g); BIO_printf(bio_err,"This is going to take a long time\n"); if(!dh || !DH_generate_parameters_ex(dh, num, g, &cb)) { if(dh) DH_free(dh); ERR_print_errors(bio_err); goto end; } } app_RAND_write_file(NULL, bio_err); } else { in=BIO_new(BIO_s_file()); if (in == NULL) { ERR_print_errors(bio_err); goto end; } if (infile == NULL) BIO_set_fp(in,stdin,BIO_NOCLOSE); else { if (BIO_read_filename(in,infile) <= 0) { perror(infile); goto end; } } if (informat != FORMAT_ASN1 && informat != FORMAT_PEM) { BIO_printf(bio_err,"bad input format specified\n"); goto end; } #ifndef OPENSSL_NO_DSA if (dsaparam) { DSA *dsa; if (informat == FORMAT_ASN1) dsa=d2i_DSAparams_bio(in,NULL); else /* informat == FORMAT_PEM */ dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL); if (dsa == NULL) { BIO_printf(bio_err,"unable to load DSA parameters\n"); ERR_print_errors(bio_err); goto end; } dh = DSA_dup_DH(dsa); DSA_free(dsa); if (dh == NULL) { ERR_print_errors(bio_err); goto end; } } else #endif { if (informat == FORMAT_ASN1) dh=d2i_DHparams_bio(in,NULL); else /* informat == FORMAT_PEM */ dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL); if (dh == NULL) { BIO_printf(bio_err,"unable to load DH parameters\n"); ERR_print_errors(bio_err); goto end; } } /* dh != NULL */ } out=BIO_new(BIO_s_file()); if (out == NULL) { ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out,stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outfile) <= 0) { perror(outfile); goto end; } } if (text) { DHparams_print(out,dh); } if (check) { if (!DH_check(dh,&i)) { ERR_print_errors(bio_err); goto end; } if (i & DH_CHECK_P_NOT_PRIME) printf("p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) printf("p value is not a safe prime\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) printf("unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) printf("the g value is not a generator\n"); if (i == 0) printf("DH parameters appear to be ok.\n"); } if (C) { unsigned char *data; int len,l,bits; len=BN_num_bytes(dh->p); bits=BN_num_bits(dh->p); data=(unsigned char *)OPENSSL_malloc(len); if (data == NULL) { perror("OPENSSL_malloc"); goto end; } printf("#ifndef HEADER_DH_H\n" "#include <openssl/dh.h>\n" "#endif\n"); printf("DH *get_dh%d()\n\t{\n",bits); l=BN_bn2bin(dh->p,data); printf("\tstatic unsigned char dh%d_p[]={",bits); for (i=0; i<l; i++) { if ((i%12) == 0) printf("\n\t\t"); printf("0x%02X,",data[i]); } printf("\n\t\t};\n"); l=BN_bn2bin(dh->g,data); printf("\tstatic unsigned char dh%d_g[]={",bits); for (i=0; i<l; i++) { if ((i%12) == 0) printf("\n\t\t"); printf("0x%02X,",data[i]); } printf("\n\t\t};\n"); printf("\tDH *dh;\n\n"); printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n"); printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n", bits,bits); printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n", bits,bits); printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n"); printf("\t\t{ DH_free(dh); return(NULL); }\n"); if (dh->length) printf("\tdh->length = %ld;\n", dh->length); printf("\treturn(dh);\n\t}\n"); OPENSSL_free(data); } if (!noout) { if (outformat == FORMAT_ASN1) i=i2d_DHparams_bio(out,dh); else if (outformat == FORMAT_PEM) i=PEM_write_bio_DHparams(out,dh); else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err,"unable to write DH parameters\n"); ERR_print_errors(bio_err); goto end; } } ret=0; end: if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); if (dh != NULL) DH_free(dh); apps_shutdown(); OPENSSL_EXIT(ret); }
BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) { BIO *b; EVP_CIPHER_CTX *ctx; const EVP_CIPHER *ciph; X509_ALGOR *calg = ec->contentEncryptionAlgorithm; unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; unsigned char *tkey = NULL; size_t tkeylen; int ok = 0; int enc, keep_key = 0; enc = ec->cipher ? 1 : 0; b = BIO_new(BIO_f_cipher()); if (!b) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); return NULL; } BIO_get_cipher_ctx(b, &ctx); if (enc) { ciph = ec->cipher; /* If not keeping key set cipher to NULL so subsequent calls * decrypt. */ if (ec->key) ec->cipher = NULL; } else { ciph = EVP_get_cipherbyobj(calg->algorithm); if (!ciph) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER); goto err; } } if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } if (enc) { int ivlen; calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); /* Generate a random IV if we need one */ ivlen = EVP_CIPHER_CTX_iv_length(ctx); if (ivlen > 0) { if (RAND_pseudo_bytes(iv, ivlen) <= 0) goto err; piv = iv; } } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } /* Generate random session key */ if (!enc || !ec->key) { tkeylen = EVP_CIPHER_CTX_key_length(ctx); tkey = OPENSSL_malloc(tkeylen); if (!tkey) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) goto err; } if (!ec->key) { ec->key = tkey; ec->keylen = tkeylen; tkey = NULL; if (enc) keep_key = 1; else ERR_clear_error(); } if (ec->keylen != tkeylen) { /* If necessary set key length */ if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) { /* Only reveal failure if debugging so we don't * leak information which may be useful in MMA. */ if (ec->debug) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_INVALID_KEY_LENGTH); goto err; } else { /* Use random key */ OPENSSL_cleanse(ec->key, ec->keylen); OPENSSL_free(ec->key); ec->key = tkey; ec->keylen = tkeylen; tkey = NULL; ERR_clear_error(); } } } if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_INITIALISATION_ERROR); goto err; } if (piv) { calg->parameter = ASN1_TYPE_new(); if (!calg->parameter) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) { CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); goto err; } } ok = 1; err: if (ec->key && !keep_key) { OPENSSL_cleanse(ec->key, ec->keylen); OPENSSL_free(ec->key); ec->key = NULL; } if (tkey) { OPENSSL_cleanse(tkey, tkeylen); OPENSSL_free(tkey); } if (ok) return b; BIO_free(b); return NULL; }
int RSA_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, RSA *rsa) { X509_SIG sig; ASN1_TYPE parameter; int i,j,ret=1; unsigned char *p, *tmps = NULL; const unsigned char *s = NULL; X509_ALGOR algor; ASN1_OCTET_STRING digest; if((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) { return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); } /* Special case: SSL signature, just check the length */ if(type == NID_md5_sha1) { if(m_len != SSL_SIG_LENGTH) { RSAerr(RSA_F_RSA_SIGN,RSA_R_INVALID_MESSAGE_LENGTH); return(0); } i = SSL_SIG_LENGTH; s = m; } else { sig.algor= &algor; sig.algor->algorithm=OBJ_nid2obj(type); if (sig.algor->algorithm == NULL) { RSAerr(RSA_F_RSA_SIGN,RSA_R_UNKNOWN_ALGORITHM_TYPE); return(0); } if (sig.algor->algorithm->length == 0) { RSAerr(RSA_F_RSA_SIGN,RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); return(0); } parameter.type=V_ASN1_NULL; parameter.value.ptr=NULL; sig.algor->parameter= ¶meter; sig.digest= &digest; sig.digest->data=(unsigned char *)m; /* TMP UGLY CAST */ sig.digest->length=m_len; i=i2d_X509_SIG(&sig,NULL); } j=RSA_size(rsa); if (i > (j-RSA_PKCS1_PADDING_SIZE)) { RSAerr(RSA_F_RSA_SIGN,RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); return(0); } if(type != NID_md5_sha1) { tmps=(unsigned char *)OPENSSL_malloc((unsigned int)j+1); if (tmps == NULL) { RSAerr(RSA_F_RSA_SIGN,ERR_R_MALLOC_FAILURE); return(0); } p=tmps; i2d_X509_SIG(&sig,&p); s=tmps; } i=RSA_private_encrypt(i,s,sigret,rsa,RSA_PKCS1_PADDING); if (i <= 0) ret=0; else *siglen=i; if(type != NID_md5_sha1) { OPENSSL_cleanse(tmps,(unsigned int)j+1); OPENSSL_free(tmps); } return(ret); }
int main(int argc, char *argv[]) { DH *a; DH *b=NULL; char buf[12]; unsigned char *abuf=NULL,*bbuf=NULL; int i,alen,blen,aout,bout,ret=1; BIO *out; CRYPTO_malloc_debug_init(); CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); #ifdef OPENSSL_SYS_WIN32 CRYPTO_malloc_init(); #endif RAND_seed(rnd_seed, sizeof rnd_seed); out=BIO_new(BIO_s_file()); if (out == NULL) EXIT(1); BIO_set_fp(out,stdout,BIO_NOCLOSE); a=DH_generate_parameters(64,DH_GENERATOR_5,cb,out); if (a == NULL) goto err; if (!DH_check(a, &i)) goto err; if (i & DH_CHECK_P_NOT_PRIME) BIO_puts(out, "p value is not prime\n"); if (i & DH_CHECK_P_NOT_SAFE_PRIME) BIO_puts(out, "p value is not a safe prime\n"); if (i & DH_UNABLE_TO_CHECK_GENERATOR) BIO_puts(out, "unable to check the generator value\n"); if (i & DH_NOT_SUITABLE_GENERATOR) BIO_puts(out, "the g value is not a generator\n"); BIO_puts(out,"\np ="); BN_print(out,a->p); BIO_puts(out,"\ng ="); BN_print(out,a->g); BIO_puts(out,"\n"); b=DH_new(); if (b == NULL) goto err; b->p=BN_dup(a->p); b->g=BN_dup(a->g); if ((b->p == NULL) || (b->g == NULL)) goto err; if (!DH_generate_key(a)) goto err; BIO_puts(out,"pri 1="); BN_print(out,a->priv_key); BIO_puts(out,"\npub 1="); BN_print(out,a->pub_key); BIO_puts(out,"\n"); if (!DH_generate_key(b)) goto err; BIO_puts(out,"pri 2="); BN_print(out,b->priv_key); BIO_puts(out,"\npub 2="); BN_print(out,b->pub_key); BIO_puts(out,"\n"); alen=DH_size(a); abuf=(unsigned char *)OPENSSL_malloc(alen); aout=DH_compute_key(abuf,b->pub_key,a); BIO_puts(out,"key1 ="); for (i=0; i<aout; i++) { sprintf(buf,"%02X",abuf[i]); BIO_puts(out,buf); } BIO_puts(out,"\n"); blen=DH_size(b); bbuf=(unsigned char *)OPENSSL_malloc(blen); bout=DH_compute_key(bbuf,a->pub_key,b); BIO_puts(out,"key2 ="); for (i=0; i<bout; i++) { sprintf(buf,"%02X",bbuf[i]); BIO_puts(out,buf); } BIO_puts(out,"\n"); if ((aout < 4) || (bout != aout) || (memcmp(abuf,bbuf,aout) != 0)) { fprintf(stderr,"Error in DH routines\n"); ret=1; } else ret=0; err: ERR_print_errors_fp(stderr); if (abuf != NULL) OPENSSL_free(abuf); if (bbuf != NULL) OPENSSL_free(bbuf); if(b != NULL) DH_free(b); if(a != NULL) DH_free(a); BIO_free(out); CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); CRYPTO_mem_leaks_fp(stderr); EXIT(ret); return(ret); }
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { EVP_MD_CTX_clear_flags(ctx,EVP_MD_CTX_FLAG_CLEANED); #ifndef OPENSSL_NO_ENGINE /* Whether it's nice or not, "Inits" can be used on "Final"'d contexts * so this context may already have an ENGINE! Try to avoid releasing * the previous handle, re-querying for an ENGINE, and having a * reinitialisation, when it may all be unecessary. */ if (ctx->engine && ctx->digest && (!type || (type && (type->type == ctx->digest->type)))) goto skip_to_init; if (type) { /* Ensure an ENGINE left lying around from last time is cleared * (the previous check attempted to avoid this if the same * ENGINE and EVP_MD could be used). */ if(ctx->engine) ENGINE_finish(ctx->engine); if(impl) { if (!ENGINE_init(impl)) { EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR); return 0; } } else /* Ask if an ENGINE is reserved for this job */ impl = ENGINE_get_digest_engine(type->type); if(impl) { /* There's an ENGINE for this job ... (apparently) */ const EVP_MD *d = ENGINE_get_digest(impl, type->type); if(!d) { /* Same comment from evp_enc.c */ EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_INITIALIZATION_ERROR); return 0; } /* We'll use the ENGINE's private digest definition */ type = d; /* Store the ENGINE functional reference so we know * 'type' came from an ENGINE and we need to release * it when done. */ ctx->engine = impl; } else ctx->engine = NULL; } else if(!ctx->digest) { EVPerr(EVP_F_EVP_DIGESTINIT_EX,EVP_R_NO_DIGEST_SET); return 0; } #endif if (ctx->digest != type) { if (ctx->digest && ctx->digest->ctx_size) OPENSSL_free(ctx->md_data); ctx->digest=type; if (type->ctx_size) ctx->md_data=OPENSSL_malloc(type->ctx_size); } #ifndef OPENSSL_NO_ENGINE skip_to_init: #endif return ctx->digest->init(ctx); }
int dtls_get_data (int s, SSL_CTX *ctx) { char *buf = NULL; fd_set readfds; int ret = 1, width = 0; int i = 0; SSL *con = NULL; BIO *sbio = NULL; int bufsize = BUFSIZ; bio_err = BIO_new_fp (stderr, BIO_NOCLOSE); bio_s_out = BIO_new_fp (stderr, BIO_NOCLOSE); if ((buf = OPENSSL_malloc (bufsize)) == NULL) { BIO_printf (bio_err, "out of memory\n"); goto ERR; } if (con == NULL) { con = SSL_new(ctx); } SSL_clear (con); if (SSL_version (con) == DTLS1_VERSION) { struct timeval timeout; sbio = BIO_new_dgram (s, BIO_NOCLOSE); timeout.tv_sec = 5; timeout.tv_usec = 0; BIO_ctrl (sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout); timeout.tv_sec = 5; timeout.tv_usec = 0; BIO_ctrl (sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout); /* want to do MTU discovery */ BIO_ctrl (sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL); /* turn on cookie exchange */ SSL_set_options (con, SSL_OP_COOKIE_EXCHANGE); // fprintf (stderr, "%s: %s(): DTLSv1 Initialization done\n", __FILE__, __func__); } SSL_set_bio (con, sbio, sbio); SSL_set_accept_state (con); /* SSL_set_fd(con,s); */ width = s + 1; for (;;) { int read_from_terminal; int read_from_sslcon; read_from_terminal = 0; read_from_sslcon = SSL_pending (con); if (!read_from_sslcon) { struct timeval tv; FD_ZERO(&readfds); FD_SET(s, &readfds); tv.tv_sec = 1; tv.tv_usec = 0; i = select(width, (void *)&readfds, NULL, NULL, &tv); if (i < 0) { continue; } if (FD_ISSET (s, &readfds)) { read_from_sslcon = 1; } else { ret = 2; goto shut; } } if (read_from_sslcon) { if (!SSL_is_init_finished(con)) { i = init_ssl_connection(con); if (i < 0) { ret = 0; goto ERR; } else if (i == 0) { ret = 1; goto ERR; } } else { AGAIN: i = SSL_read (con, (char *) buf, bufsize); switch (SSL_get_error (con, i)) { case SSL_ERROR_NONE: write (fileno (stdout), buf, (unsigned int) i); if (SSL_pending(con)) { fprintf (stderr, "%s: %s(): Some more seems to be coming... "\ "letz wait for that\n", __FILE__, __func__); goto AGAIN; } else fprintf (stderr, "%s(): Hey, itz all over boss... do finishing "\ "ceremony\n", __func__); ret = 0; goto ERR; case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_X509_LOOKUP: BIO_printf(bio_s_out,"Read BLOCK\n"); break; case SSL_ERROR_SYSCALL: case SSL_ERROR_SSL: BIO_printf(bio_s_out,"ERROR\n"); ERR_print_errors(bio_err); ret = 1; goto ERR; case SSL_ERROR_ZERO_RETURN: BIO_printf(bio_s_out,"\nDONE\n"); ret = 0; goto ERR; } } } } ERR: if (0 == ret) { char temp [] = "ACK from SERVER: READ SUCCESSFULLY DONE\n"; for (;;) { i = SSL_write (con, temp, strlen (temp)); switch (SSL_get_error (con, i)) { case SSL_ERROR_NONE: if (SSL_pending (con)) break; else goto WRITEDONE; case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_X509_LOOKUP: BIO_printf (bio_s_out, "Write BLOCK\n"); break; case SSL_ERROR_SYSCALL: case SSL_ERROR_SSL: BIO_printf (bio_s_out, "ERROR\n"); ERR_print_errors (bio_err); ret = 1; goto WRITEDONE; case SSL_ERROR_ZERO_RETURN: BIO_printf (bio_s_out, "\nDONE\n"); ret = 1; goto WRITEDONE; } } } WRITEDONE: #ifdef DEBUG BIO_printf (bio_s_out, "shutting down SSL\n"); print_stats (bio_s_out, ctx); #endif #if 1 SSL_set_shutdown (con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); #else SSL_shutdown(con); #endif shut: if (con != NULL) SSL_free (con); if (2 != ret) BIO_printf(bio_s_out,"CONNECTION CLOSED\n"); if (buf != NULL) { OPENSSL_cleanse (buf, bufsize); OPENSSL_free (buf); } if ((ret >= 0) && (2 != ret)) BIO_printf (bio_s_out, "ACCEPT\n"); return(ret); }
int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) { int i,first,len=0,c, use_bn; char ftmp[24], *tmp = ftmp; int tmpsize = sizeof ftmp; const char *p; unsigned long l; BIGNUM *bl = NULL; if (num == 0) return(0); else if (num == -1) num=TINYCLR_SSL_STRLEN(buf); p=buf; c= *(p++); num--; if ((c >= '0') && (c <= '2')) { first= c-'0'; } else { ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE); goto err; } if (num <= 0) { ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER); goto err; } c= *(p++); num--; for (;;) { if (num <= 0) break; if ((c != '.') && (c != ' ')) { ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_SEPARATOR); goto err; } l=0; use_bn = 0; for (;;) { if (num <= 0) break; num--; c= *(p++); if ((c == ' ') || (c == '.')) break; if ((c < '0') || (c > '9')) { ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT); goto err; } if (!use_bn && l > (ULONG_MAX / 10L)) { use_bn = 1; if (!bl) bl = BN_new(); if (!bl || !BN_set_word(bl, l)) goto err; } if (use_bn) { if (!BN_mul_word(bl, 10L) || !BN_add_word(bl, c-'0')) goto err; } else l=l*10L+(long)(c-'0'); } if (len == 0) { if ((first < 2) && (l >= 40)) { ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE); goto err; } if (use_bn) { if (!BN_add_word(bl, first * 40)) goto err; } else l+=(long)first*40; } i=0; if (use_bn) { int blsize; blsize = BN_num_bits(bl); blsize = (blsize + 6)/7; if (blsize > tmpsize) { if (tmp != ftmp) OPENSSL_free(tmp); tmpsize = blsize + 32; tmp = (char*)OPENSSL_malloc(tmpsize); //MS: Cast to char* if (!tmp) goto err; } while(blsize--) tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L); } else { for (;;) { tmp[i++]=(unsigned char)l&0x7f; l>>=7L; if (l == 0L) break; } } if (out != NULL) { if (len+i > olen) { ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_BUFFER_TOO_SMALL); goto err; } while (--i > 0) out[len++]=tmp[i]|0x80; out[len++]=tmp[0]; } else len+=i; } if (tmp != ftmp) OPENSSL_free(tmp); if (bl) BN_free(bl); return(len); err: if (tmp != ftmp) OPENSSL_free(tmp); if (bl) BN_free(bl); return(0); }
int tls1_change_cipher_state(SSL *s, int which) { static const unsigned char empty[]=""; unsigned char *p,*key_block,*mac_secret; unsigned char *exp_label,buf[TLS_MD_MAX_CONST_SIZE+ SSL3_RANDOM_SIZE*2]; unsigned char tmp1[EVP_MAX_KEY_LENGTH]; unsigned char tmp2[EVP_MAX_KEY_LENGTH]; unsigned char iv1[EVP_MAX_IV_LENGTH*2]; unsigned char iv2[EVP_MAX_IV_LENGTH*2]; unsigned char *ms,*key,*iv,*er1,*er2; int client_write; EVP_CIPHER_CTX *dd; const EVP_CIPHER *c; const SSL_COMP *comp; const EVP_MD *m; int is_export,n,i,j,k,exp_label_len,cl; int reuse_dd = 0; is_export=SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); c=s->s3->tmp.new_sym_enc; m=s->s3->tmp.new_hash; comp=s->s3->tmp.new_compression; key_block=s->s3->tmp.key_block; #ifdef KSSL_DEBUG printf("tls1_change_cipher_state(which= %d) w/\n", which); printf("\talg= %ld, comp= %p\n", s->s3->tmp.new_cipher->algorithms, comp); printf("\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c); printf("\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n", c->nid,c->block_size,c->key_len,c->iv_len); printf("\tkey_block: len= %d, data= ", s->s3->tmp.key_block_length); { int i; for (i=0; i<s->s3->tmp.key_block_length; i++) printf("%02x", key_block[i]); printf("\n"); } #endif /* KSSL_DEBUG */ if (which & SSL3_CC_READ) { if (s->enc_read_ctx != NULL) reuse_dd = 1; else if ((s->enc_read_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; dd= s->enc_read_ctx; s->read_hash=m; if (s->expand != NULL) { COMP_CTX_free(s->expand); s->expand=NULL; } if (comp != NULL) { s->expand=COMP_CTX_new(comp->method); if (s->expand == NULL) { SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } if (s->s3->rrec.comp == NULL) s->s3->rrec.comp=(unsigned char *) OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH); if (s->s3->rrec.comp == NULL) goto err; } memset(&(s->s3->read_sequence[0]),0,8); mac_secret= &(s->s3->read_mac_secret[0]); } else { if (s->enc_write_ctx != NULL) reuse_dd = 1; else if ((s->enc_write_ctx=OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) goto err; if ((s->enc_write_ctx == NULL) && ((s->enc_write_ctx=(EVP_CIPHER_CTX *) OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL)) goto err; dd= s->enc_write_ctx; s->write_hash=m; if (s->compress != NULL) { COMP_CTX_free(s->compress); s->compress=NULL; } if (comp != NULL) { s->compress=COMP_CTX_new(comp->method); if (s->compress == NULL) { SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,SSL_R_COMPRESSION_LIBRARY_ERROR); goto err2; } } memset(&(s->s3->write_sequence[0]),0,8); mac_secret= &(s->s3->write_mac_secret[0]); } if (reuse_dd) EVP_CIPHER_CTX_cleanup(dd); EVP_CIPHER_CTX_init(dd); p=s->s3->tmp.key_block; i=EVP_MD_size(m); cl=EVP_CIPHER_key_length(c); j=is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ k=EVP_CIPHER_iv_length(c); er1= &(s->s3->client_random[0]); er2= &(s->s3->server_random[0]); if ( (which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { ms= &(p[ 0]); n=i+i; key= &(p[ n]); n+=j+j; iv= &(p[ n]); n+=k+k; exp_label=(unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST; exp_label_len=TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; client_write=1; } else { n=i; ms= &(p[ n]); n+=i+j; key= &(p[ n]); n+=j+k; iv= &(p[ n]); n+=k; exp_label=(unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST; exp_label_len=TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; client_write=0; } if (n > s->s3->tmp.key_block_length) { SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_INTERNAL_ERROR); goto err2; } memcpy(mac_secret,ms,i); #ifdef TLS_DEBUG printf("which = %04X\nmac key=",which); { int z; for (z=0; z<i; z++) printf("%02X%c",ms[z],((z+1)%16)?' ':'\n'); } #endif if (is_export) { /* In here I set both the read and write key/iv to the * same value since only the correct one will be used :-). */ p=buf; memcpy(p,exp_label,exp_label_len); p+=exp_label_len; memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); p+=SSL3_RANDOM_SIZE; memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); p+=SSL3_RANDOM_SIZE; tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,(int)(p-buf),key,j, tmp1,tmp2,EVP_CIPHER_key_length(c)); key=tmp1; if (k > 0) { p=buf; memcpy(p,TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE); p+=TLS_MD_IV_BLOCK_CONST_SIZE; memcpy(p,s->s3->client_random,SSL3_RANDOM_SIZE); p+=SSL3_RANDOM_SIZE; memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); p+=SSL3_RANDOM_SIZE; tls1_PRF(s->ctx->md5,s->ctx->sha1,buf,p-buf,empty,0, iv1,iv2,k*2); if (client_write) iv=iv1; else iv= &(iv1[k]); } } s->session->key_arg_length=0; #ifdef KSSL_DEBUG { int i; printf("EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); printf("\tkey= "); for (i=0; i<c->key_len; i++) printf("%02x", key[i]); printf("\n"); printf("\t iv= "); for (i=0; i<c->iv_len; i++) printf("%02x", iv[i]); printf("\n"); } #endif /* KSSL_DEBUG */ EVP_CipherInit_ex(dd,c,NULL,key,iv,(which & SSL3_CC_WRITE)); #ifdef TLS_DEBUG printf("which = %04X\nkey=",which); { int z; for (z=0; z<EVP_CIPHER_key_length(c); z++) printf("%02X%c",key[z],((z+1)%16)?' ':'\n'); } printf("\niv="); { int z; for (z=0; z<k; z++) printf("%02X%c",iv[z],((z+1)%16)?' ':'\n'); } printf("\n"); #endif OPENSSL_cleanse(tmp1,sizeof(tmp1)); OPENSSL_cleanse(tmp2,sizeof(tmp1)); OPENSSL_cleanse(iv1,sizeof(iv1)); OPENSSL_cleanse(iv2,sizeof(iv2)); return(1); err: SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE,ERR_R_MALLOC_FAILURE); err2: return(0); }
/* signing */ static int rsa_ossl_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret, *res; int i, j, k, num = 0, r = -1; unsigned char *buf = NULL; BN_CTX *ctx = NULL; int local_blinding = 0; /* * Used only if the blinding structure is shared. A non-NULL unblind * instructs rsa_blinding_convert() and rsa_blinding_invert() to store * the unblinding factor outside the blinding structure. */ BIGNUM *unblind = NULL; BN_BLINDING *blinding = NULL; if ((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (f == NULL || ret == NULL || buf == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } switch (padding) { case RSA_PKCS1_PADDING: i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen); break; case RSA_X931_PADDING: i = RSA_padding_add_X931(buf, num, from, flen); break; case RSA_NO_PADDING: i = RSA_padding_add_none(buf, num, from, flen); break; case RSA_SSLV23_PADDING: default: RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (i <= 0) goto err; if (BN_bin2bn(buf, num, f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { /* usually the padding functions would catch this */ RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { blinding = rsa_get_blinding(rsa, &local_blinding, ctx); if (blinding == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); goto err; } } if (blinding != NULL) { if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } if (!rsa_blinding_convert(blinding, f, unblind, ctx)) goto err; } if ((rsa->flags & RSA_FLAG_EXT_PKEY) || ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) goto err; } else { BIGNUM *d = NULL, *local_d = NULL; if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { local_d = d = BN_new(); if (d == NULL) { RSAerr(RSA_F_RSA_OSSL_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); goto err; } BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); } else { d = rsa->d; } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) { BN_free(local_d); goto err; } if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, rsa->_method_mod_n)) { BN_free(local_d); goto err; } /* We MUST free local_d before any further use of rsa->d */ BN_free(local_d); } if (blinding) if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) goto err; if (padding == RSA_X931_PADDING) { BN_sub(f, rsa->n, ret); if (BN_cmp(ret, f) > 0) res = f; else res = ret; } else res = ret; /* * put in leading 0 bytes if the number is less than the length of the * modulus */ j = BN_num_bytes(res); i = BN_bn2bin(res, &(to[num - j])); for (k = 0; k < (num - i); k++) to[k] = 0; r = num; err: if (ctx != NULL) BN_CTX_end(ctx); BN_CTX_free(ctx); OPENSSL_clear_free(buf, num); return (r); }
int tls1_setup_key_block(SSL *s) { unsigned char *p1,*p2; const EVP_CIPHER *c; const EVP_MD *hash; int num; SSL_COMP *comp; #ifdef KSSL_DEBUG printf ("tls1_setup_key_block()\n"); #endif /* KSSL_DEBUG */ if (s->s3->tmp.key_block_length != 0) return(1); if (!ssl_cipher_get_evp(s->session,&c,&hash,&comp)) { SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,SSL_R_CIPHER_OR_HASH_UNAVAILABLE); return(0); } s->s3->tmp.new_sym_enc=c; s->s3->tmp.new_hash=hash; num=EVP_CIPHER_key_length(c)+EVP_MD_size(hash)+EVP_CIPHER_iv_length(c); num*=2; ssl3_cleanup_key_block(s); if ((p1=(unsigned char *)OPENSSL_malloc(num)) == NULL) goto err; if ((p2=(unsigned char *)OPENSSL_malloc(num)) == NULL) goto err; s->s3->tmp.key_block_length=num; s->s3->tmp.key_block=p1; #ifdef TLS_DEBUG printf("client random\n"); { int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->client_random[z],((z+1)%16)?' ':'\n'); } printf("server random\n"); { int z; for (z=0; z<SSL3_RANDOM_SIZE; z++) printf("%02X%c",s->s3->server_random[z],((z+1)%16)?' ':'\n'); } printf("pre-master\n"); { int z; for (z=0; z<s->session->master_key_length; z++) printf("%02X%c",s->session->master_key[z],((z+1)%16)?' ':'\n'); } #endif tls1_generate_key_block(s,p1,p2,num); OPENSSL_cleanse(p2,num); OPENSSL_free(p2); #ifdef TLS_DEBUG printf("\nkey block\n"); { int z; for (z=0; z<num; z++) printf("%02X%c",p1[z],((z+1)%16)?' ':'\n'); } #endif if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) { /* enable vulnerability countermeasure for CBC ciphers with * known-IV problem (http://www.openssl.org/~bodo/tls-cbc.txt) */ s->s3->need_empty_fragments = 1; if (s->session->cipher != NULL) { if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_eNULL) s->s3->need_empty_fragments = 0; #ifndef OPENSSL_NO_RC4 if ((s->session->cipher->algorithms & SSL_ENC_MASK) == SSL_RC4) s->s3->need_empty_fragments = 0; #endif } } return(1); err: SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK,ERR_R_MALLOC_FAILURE); return(0); }
/* signature verification */ static int rsa_ossl_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) { BIGNUM *f, *ret; int i, num = 0, r = -1; unsigned char *p; unsigned char *buf = NULL; BN_CTX *ctx = NULL; if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); return -1; } if (BN_ucmp(rsa->n, rsa->e) <= 0) { RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); return -1; } /* for large moduli, enforce exponent limit */ if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); return -1; } } if ((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); ret = BN_CTX_get(ctx); num = BN_num_bytes(rsa->n); buf = OPENSSL_malloc(num); if (f == NULL || ret == NULL || buf == NULL) { RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, ERR_R_MALLOC_FAILURE); goto err; } /* * This check was for equality but PGP does evil things and chops off the * top '0' bytes */ if (flen > num) { RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN); goto err; } if (BN_bin2bn(from, flen, f) == NULL) goto err; if (BN_ucmp(f, rsa->n) >= 0) { RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_DATA_TOO_LARGE_FOR_MODULUS); goto err; } if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) if (!BN_MONT_CTX_set_locked (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) goto err; if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, rsa->_method_mod_n)) goto err; if ((padding == RSA_X931_PADDING) && ((bn_get_words(ret)[0] & 0xf) != 12)) if (!BN_sub(ret, rsa->n, ret)) goto err; p = buf; i = BN_bn2bin(ret, p); switch (padding) { case RSA_PKCS1_PADDING: r = RSA_padding_check_PKCS1_type_1(to, num, buf, i, num); break; case RSA_X931_PADDING: r = RSA_padding_check_X931(to, num, buf, i, num); break; case RSA_NO_PADDING: r = RSA_padding_check_none(to, num, buf, i, num); break; default: RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); goto err; } if (r < 0) RSAerr(RSA_F_RSA_OSSL_PUBLIC_DECRYPT, RSA_R_PADDING_CHECK_FAILED); err: if (ctx != NULL) BN_CTX_end(ctx); BN_CTX_free(ctx); OPENSSL_clear_free(buf, num); return (r); }
CERT *ssl_cert_dup(CERT *cert) { CERT *ret; int i; ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); if (ret == NULL) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE); return(NULL); } memset(ret, 0, sizeof(CERT)); ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; /* or ret->key = ret->pkeys + (cert->key - cert->pkeys), * if you find that more readable */ ret->mask_k = cert->mask_k; ret->mask_a = cert->mask_a; if (cert->dh_tmp != NULL) { ret->dh_tmp = DHparams_dup(cert->dh_tmp); if (ret->dh_tmp == NULL) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_DH_LIB); goto err; } if (cert->dh_tmp->priv_key) { BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); if (!b) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_BN_LIB); goto err; } ret->dh_tmp->priv_key = b; } if (cert->dh_tmp->pub_key) { BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); if (!b) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_BN_LIB); goto err; } ret->dh_tmp->pub_key = b; } } ret->dh_tmp_cb = cert->dh_tmp_cb; if (cert->ecdh_tmp) { ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); if (ret->ecdh_tmp == NULL) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_EC_LIB); goto err; } } ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; for (i = 0; i < SSL_PKEY_NUM; i++) { CERT_PKEY *cpk = cert->pkeys + i; CERT_PKEY *rpk = ret->pkeys + i; if (cpk->x509 != NULL) { rpk->x509 = X509_up_ref(cpk->x509); } if (cpk->privatekey != NULL) { rpk->privatekey = cpk->privatekey; CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY); switch(i) { /* If there was anything special to do for * certain types of keys, we'd do it here. * (Nothing at the moment, I think.) */ case SSL_PKEY_RSA_ENC: case SSL_PKEY_RSA_SIGN: /* We have an RSA key. */ break; case SSL_PKEY_ECC: /* We have an ECC key */ break; default: /* Can't happen. */ OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, SSL_R_LIBRARY_BUG); } } if (cpk->chain) { rpk->chain = X509_chain_up_ref(cpk->chain); if (!rpk->chain) { OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE); goto err; } } } /* Peer sigalgs set to NULL as we get these from handshake too */ ret->peer_sigalgs = NULL; ret->peer_sigalgslen = 0; /* Configured sigalgs however we copy across */ if (cert->conf_sigalgs) { ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen); if (!ret->conf_sigalgs) goto err; memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen); ret->conf_sigalgslen = cert->conf_sigalgslen; } else ret->conf_sigalgs = NULL; if (cert->client_sigalgs) { ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen); if (!ret->client_sigalgs) goto err; memcpy(ret->client_sigalgs, cert->client_sigalgs, cert->client_sigalgslen); ret->client_sigalgslen = cert->client_sigalgslen; } else ret->client_sigalgs = NULL; /* Shared sigalgs also NULL */ ret->shared_sigalgs = NULL; /* Copy any custom client certificate types */ if (cert->client_certificate_types) { ret->client_certificate_types = BUF_memdup( cert->client_certificate_types, cert->num_client_certificate_types); if (!ret->client_certificate_types) goto err; ret->num_client_certificate_types = cert->num_client_certificate_types; } ret->cert_flags = cert->cert_flags; ret->cert_cb = cert->cert_cb; ret->cert_cb_arg = cert->cert_cb_arg; if (cert->verify_store) { CRYPTO_add(&cert->verify_store->references, 1, CRYPTO_LOCK_X509_STORE); ret->verify_store = cert->verify_store; } if (cert->chain_store) { CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE); ret->chain_store = cert->chain_store; } ret->ciphers_raw = NULL; return(ret); err: ssl_cert_free(ret); return NULL; }
/* type is a 'bitmap' of acceptable string types. */ ASN1_STRING *d2i_ASN1_type_bytes (ASN1_STRING ** a, const unsigned char **pp, long length, int type) { ASN1_STRING *ret = NULL; const unsigned char *p; unsigned char *s; long len; int inf, tag, xclass; int i = 0; p = *pp; inf = ASN1_get_object (&p, &len, &tag, &xclass, length); if (inf & 0x80) goto err; if (tag >= 32) { i = ASN1_R_TAG_VALUE_TOO_HIGH; goto err; } if (!(ASN1_tag2bit (tag) & type)) { i = ASN1_R_WRONG_TYPE; goto err; } /* If a bit-string, exit early */ if (tag == V_ASN1_BIT_STRING) return (d2i_ASN1_BIT_STRING (a, pp, length)); if ((a == NULL) || ((*a) == NULL)) { if ((ret = ASN1_STRING_new ()) == NULL) return (NULL); } else ret = (*a); if (len != 0) { s = (unsigned char *) OPENSSL_malloc ((int) len + 1); if (s == NULL) { i = ERR_R_MALLOC_FAILURE; goto err; } memcpy (s, p, (int) len); s[len] = '\0'; p += len; } else s = NULL; if (ret->data != NULL) OPENSSL_free (ret->data); ret->length = (int) len; ret->data = s; ret->type = tag; if (a != NULL) (*a) = ret; *pp = p; return (ret); err: ASN1err (ASN1_F_D2I_ASN1_TYPE_BYTES, i); if ((ret != NULL) && ((a == NULL) || (*a != ret))) ASN1_STRING_free (ret); return (NULL); }
int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *callback, void *u) { EVP_CIPHER_CTX *ctx = NULL; int dsize = 0, i = 0, j = 0, ret = 0; unsigned char *p, *data = NULL; const char *objstr = NULL; char buf[PEM_BUFSIZE]; unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; if (enc != NULL) { objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); if (objstr == NULL) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER); goto err; } } if ((dsize = i2d(x, NULL)) < 0) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB); dsize = 0; goto err; } /* dzise + 8 bytes are needed */ /* actually it needs the cipher block size extra... */ data = OPENSSL_malloc((unsigned int)dsize + 20); if (data == NULL) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_MALLOC_FAILURE); goto err; } p = data; i = i2d(x, &p); if (enc != NULL) { if (kstr == NULL) { if (callback == NULL) klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); else klen = (*callback) (buf, PEM_BUFSIZE, 1, u); if (klen <= 0) { PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_READ_KEY); goto err; } #ifdef CHARSET_EBCDIC /* Convert the pass phrase from EBCDIC */ ebcdic2ascii(buf, buf, klen); #endif kstr = (unsigned char *)buf; } RAND_add(data, i, 0); /* put in the RSA key. */ OPENSSL_assert(EVP_CIPHER_iv_length(enc) <= (int)sizeof(iv)); if (RAND_bytes(iv, EVP_CIPHER_iv_length(enc)) <= 0) /* Generate a salt */ goto err; /* * The 'iv' is used as the iv and as a salt. It is NOT taken from * the BytesToKey function */ if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL)) goto err; if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf, PEM_BUFSIZE); OPENSSL_assert(strlen(objstr) + 23 + 2 * EVP_CIPHER_iv_length(enc) + 13 <= sizeof buf); buf[0] = '\0'; PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); PEM_dek_info(buf, objstr, EVP_CIPHER_iv_length(enc), (char *)iv); /* k=strlen(buf); */ ret = 1; if ((ctx = EVP_CIPHER_CTX_new()) == NULL || !EVP_EncryptInit_ex(ctx, enc, NULL, key, iv) || !EVP_EncryptUpdate(ctx, data, &j, data, i) || !EVP_EncryptFinal_ex(ctx, &(data[j]), &i)) ret = 0; if (ret == 0) goto err; i += j; } else { ret = 1; buf[0] = '\0'; } i = PEM_write_bio(bp, name, buf, data, i); if (i <= 0) ret = 0; err: OPENSSL_cleanse(key, sizeof(key)); OPENSSL_cleanse(iv, sizeof(iv)); EVP_CIPHER_CTX_free(ctx); OPENSSL_cleanse(buf, PEM_BUFSIZE); OPENSSL_clear_free(data, (unsigned int)dsize); return (ret); }