Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

PEM series of Openssl

2025-02-25 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)06/01 Report--

PEM series of Openssl

Introduction to the structure of 1.PEM coding file

The full name of PEM is Privacy Enhanced Mail, which defines the encryption of a standard ready to send mail, which is mainly used to save various objects in PEM format and read various objects in PEM format into the corresponding structure. The basic process is as follows:

Convert the information to ASCII code or other encoding; encrypt the converted email message using a symmetric algorithm; encode the encrypted email message using BASE64; encapsulate the information with some header definitions in the following format (not necessarily required, optional):

Proc-Type,4:ENCRYPTED

DEK-Info: cipher-name, where the first header message indicates whether the file is encrypted. Possible values of the header information include ENCRYPTED (the message is encrypted and signed), MIC-ONLY (the message is digitally signed but not encrypted), and MIC-CLEAR (the message is digitally signed but not encrypted or encoded Can be read in non-PEM format) and CLEAR (the message is unsigned and encrypted and not encoded, this item seems to be an extension of openssl itself, but it is not really implemented) The second header indicates the encryption algorithm and the ivec parameters used. In fact, ivec should provide a randomly generated data sequence here, which is different from the initialization variable (IV) used in the block encryption algorithm.

Add the following header information to the front of the information:

-- BEGIN PRIVACY-ENHANCED MESSAGE--

Add the following form of trailing information to the end of the information:

-- END PRIVACY-ENHANCED MESSAGE--

The above is the basic structure of openssl's PEM file, it should be noted that Openssl does not implement all the standards of PEM, it only implements some options that need to be used in openssl. For detailed PEM format, please refer to RFC1421-1424.

Here is an example of an encrypted DSA private key encoded by PEM:

-- BEGIN DSA PRIVATE KEY--

Proc-Type: 4,ENCRYPTED

DEK-Info: DES-EDE3-CBC,F80EEEBEEA7386C4

GZ9zgFcHOlnhPoiSbVi/yXc9mGoj44A6IveD4UlpSEUt6Xbse3Fr0KHIUyQ3oGnSmClKoAp/eOTb5Frhto85SzdsxYtac+X1v5XwdzAMy2KowHVk1N8A5jmE2OlkNPNtof132MNlo2cyIRYaa35PPYBGNCmUm7YcYS8O90YtkrQZZTf4+2C4kllhMcdkQwkrFWSWC8YOQ7w0LHb4cX1FejHHom9Nd/0PN3vn3UyySvfOqoR7nbXkrpHXmPIr0hxXRcF0aXcV/CzZ1/nfXWQf4o3+oD0T22SDoVcZY60IzI0oIc3pNCbDV3uKNmgekrFdqOUJ+QW8oWp7oefRx62iBfIeC8DZunohMXaWAQCU0sLQOR4yEdeUCnzCSywe0bG1diD0KYaEe+Yub1BQH4aLsBgDjardgpJRTQLq0DUvw0/QGO1irKTJzegEDNVBKrVnV4AHOKT1CUKqvGNRP1UnccUDTF6miOAtaj/qpzra7sSk7dkGBvIEeFoAg84kfh9hhVvF1YyzC9bwZepruoqoUwke/WdNIR5ymOVZ/4Liw0JdIOcq+atbdRX08niqIRkfdsZrUj4leo3zdefYUQ7w4N2Ns37yDFq7

-- END DSA PRIVATE KEY--

Sometimes what is encoded by PEM is not encrypted, but simply encoded by BASE64. Here is an example of a certificate request without encryption:

-- BEGIN CERTIFICATE REQUEST--

MIICVTCCAhMCAQAwUzELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAxMDUENBMIIBtTCCASkGBSsOAwIMMIIBHgKBgQCnP26Fv0FqKX3wn0cZMJCaCR3aajMexT2GlrMV4FMuj+BZgnOQPnUxmUd6UvuF5NmmezibaIqEm4fGHrV+hktTW1nPcWUZiG7OZq5riDb77Cjcwtelu+UsOSZL2ppwGJU3lRBWI/YV7boEXt45T/23Qx+1pGVvzYAR5HCVW1DNSQIVAPcHMe36bAYD1YWKHKycZedQZmVvAoGATd9MA6aRivUZb1BGJZnlaG8w42nh6bNdmLsohkj83pkEP1+IDJxzJA0gXbkqmj8YlifkYofBe3RiU/xhJ6h7kQmdtvFNnFQPWAbuSXQHzlV+I84W9srcWmEBfslxtU323DQph3j2XiCTs9v15AlsQReVkusBtXOlan7YMu0OArgDgYUAAoGBAKbtuR5AdW+ICjCFe2ixjUiJJzM2IKwe6NZEMXg39+HQ1UTPTmfLZLps+rZfolHDXuRKMXbGFdSF0nXYzotPCzi7GauwEJTZyr27ZZjA1C6apGSQ9GzuwNvZ4rCXystVEagAS8OQ4H3D4dWS17Zg31ICb5o4E5r0z09o/Uz46u0VoAAwCQYFKw4DAhsFAAMxADAuAhUArRubTxsbIXy3AhtjQ943AbNBnSICFQCu+g1iW3jwF+gOcbroD4S/ZcvB3w==

-- END CERTIFICATE REQUEST--

As you can see, the file does not have the first two headers. If you often use openssl applications, you will be familiar with these file formats.

Introduction to 2.PEM types and implementation structure

The PEM-related structures defined in openssl are as follows (openssl\ pem.h), which are the basis of all PEM series functions.

What is defined below is a high-level application structure of PEM, which is initialized by PEM_SealInit and finally released using PEM_SealFinal. This structure defines the coding algorithm, information summary algorithm and encryption algorithm to be used in PEM.

Typedef struct PEM_Encode_Seal_st

{

EVP_ENCODE_CTX encode

EVP_MD_CTX md

EVP_CIPHER_CTX cipher

} PEM_ENCODE_SEAL_CTX

The following defines a substructure in PEM_CTX that is used to hold the user's information

Typedef struct pem_recip_st

{

Char * name

X509_NAME * dn

Int cipher

Int key_enc

} PEM_USER

The following is the definition of the PEM main structure PEM_CTX structure, and we will explain the necessary parameters in the comments.

Typedef struct pem_ctx_st

{

Int type;// structure type

Struct

{

Int version;// version number

Int mode;// coding mode

} proc_type;//Proc_Type field information, including version number and encoding method

Char * domain

Struct

{

Int cipher

} DEK_info;// defines the information of the DEK_info field in PEM

PEM_USER * originator

Int num_recipient

PEM_USER * * recipient

# ifndef OPENSSL_NO_STACK

STACK * x509 certificate chain / save certificate chain

# else

Char * x509 certificate chain; / / Save certificate chain

# endif

EVP_MD * md; / / signature algorithm type, which specifies the information digest algorithm and signature algorithm

Whether the int md_enc; / / message digest algorithm is encrypted (signed)

Int md_len; / / length of summary information

Char * md_data; / / digest information, which can be encrypted (signed) information

EVP_CIPHER * dec;// data encryption algorithm

Int key_len; / / key length

Unsigned char * key; / / encryption key

Int data_enc; / / whether the data is encrypted

Int data_len; / / data length

Unsigned char * data; / / data

} PEM_CTX

Let's explain in detail some important parameters in the PEM_CTX structure.

2.1 int type parameters

This parameter indicates the type of PEM_CTX structure, which currently includes the following defined types:

# define PEM_OBJ_UNDEF 0

# define PEM_OBJ_X509 1

# define PEM_OBJ_X509_REQ 2

# define PEM_OBJ_CRL 3

# define PEM_OBJ_SSL_SESSION 4

# define PEM_OBJ_PRIV_KEY 10

# define PEM_OBJ_PRIV_RSA 11

# define PEM_OBJ_PRIV_DSA 12

# define PEM_OBJ_PRIV_DH 13

# define PEM_OBJ_PUB_RSA 14

# define PEM_OBJ_PUB_DSA 15

# define PEM_OBJ_PUB_DH 16

# define PEM_OBJ_DHPARAMS 17

# define PEM_OBJ_DSAPARAMS 18

# define PEM_OBJ_PRIV_RSA_PUBLIC 19

As you can see, these types basically include the basic structures to be used in all openssl

2.2 struct proc_type parameters

This parameter saves the information of the Proc_Type field in the PEM standard (refer to "PEM Series 1 of openssl"). You can see that the structure consists of two fields. The first field, version, is the version number, and the second field, mode, is the encoding method of the information. Currently, four fields are defined as follows:

# define PEM_TYPE_ENCRYPTED 10

# define PEM_TYPE_MIC_ONLY 20

# define PEM_TYPE_MIC_CLEAR 30

# define PEM_TYPE_CLEAR 40

The meaning of these four values can be found in "openssl's PEM Series 1". It is worth noting that the last PEM_TYPE_CLEAR is not actually used in the PEM file of the openssl implementation.

2.3 struct DEK_info parameters

This parameter defines the information for the DEK_info field in PEM, which should contain two fields, including the encryption algorithm and IV. However, due to historical reasons, the original non-standard IV field in openssl has been cancelled in the new version of openssl, so there is only one algorithm definition left. The currently supported algorithms are as follows:

# define PEM_DEK_DES_CBC 40

# define PEM_DEK_IDEA_CBC 45

# define PEM_DEK_DES_EDE 50

# define PEM_DEK_DES_ECB 60

# define PEM_DEK_RSA 70

# define PEM_DEK_RSA_MD2 80

# define PEM_DEK_RSA_MD5 90

Introduction to the General parameters of 3.PEM Series functions

Many of the parameters in the PEM series of functions have the same meaning, that is, they are universal. This section will introduce the meaning of these general parameters, so that the later chapters can introduce PEM series functions more conveniently and smoothly.

3.1 bp parameters

If the function has this parameter, the BIO interface for data reading and writing is defined.

3.2 fp parameters

If the function contains this parameter, the FILE pointer to read and write the data is defined.

3.3 TYPE type parameters

The series of functions for PEM read operations all have arguments to TYPE * * x and return TYEP * pointers. The TYPE here can be the structure to be used by any function, such as DSA or X509. If the parameter x is NULL, it will be ignored. If x is not NULL, but * x is NULL, then the returned structure is written to * x. If neither x nor * x is NULL, then the function attempts to reuse the structure in * x. The function here always returns a pointer to the execution structure (the value of x), or NULL if something goes wrong.

3.4 enc parameters

The enc parameter defines the encryption algorithm that the PEM function uses when writing the private key. Encryption is done at the PEM layer. If the parameter is NULL, the private key is written to the appropriate interface in an unencrypted form.

3.5 cb parameters

The cb parameter defines the callback function, which is used when a password is required to encrypt the PEM structure (typically the private key).

3.6 kstr parameters

It is mainly used in PEM write series functions. If this parameter is not NULL, then klen bytes in kstr are used as passwords. In this case, the cb parameter is ignored.

3.7 u parameter

If the cb parameter is NULL and the u parameter is not NULL, then the u parameter is a string that ends with NULL as the password. If both the cb and u arguments are NULL, the default callback function is also used, which typically prompts for a password at the current terminal and turns off the echo function.

3.8 introduction of callback function callback function

Because the default callback function is terminal-based and sometimes not suitable for use (such as GUI programs), alternative callback functions can be used. The form of the return function is as follows:

Int cb (char * buf, int size, int rwflag, void * u)

In this function, buf is the parameter that holds the password. Size takes into account the maximum length (such as the length of buf). Rwflag is a read-write flag. 0 is a read operation and 1 is a write operation. When rwflag is 1, a typical function typically asks the user to authenticate the password (such as entering it twice). The u parameter has the same meaning as the u parameter of the PEM function above, which allows the application to use fixed data as arguments to the callback function. The callback function must return the number of password characters and 0 if there is an error.

4.PEM structure information processing function

The functions introduced in this paper are functions that deal with some field information in the PEM structure, which may not be used in general applications, but a deeper application may not be avoided. In addition, understanding these applications is also beneficial to a deeper understanding of the structure of PEM. Here are the definitions of some of these related functions (openssl\ pem.h):

Int PEM_get_EVP_CIPHER_INFO (char * header, EVP_CIPHER_INFO * cipher)

Int PEM_do_header (EVP_CIPHER_INFO * cipher, unsigned char * data,long * len,pem_password_cb * callback,void * u)

Void PEM_proc_type (char * buf, int type)

Void PEM_dek_info (char * buf, const char * type, int len, char * str)

4.1 PEM_proc_type

This function returns the Proc-Type field information of a standard PEM file with a given parameter type. The returned information is written into the buf parameter, so the memory space allocated by buf must be large enough. In fact, the string returned by this function is no more than the following four results:

When type is PEM_TYPE_ENCRYPTED, the return string is "Proc-Type: 4 authentic\ n"

When type is PEM_TYPE_MIC_CLEAR, the return string is "Proc-Type: 4 MICMurCLEAR\ n"

When type is PEM_TYPE_MIC_ONLY, the return string is "Proc-Type: 4 Magi Michaeley\ n"

When type is another value, the returned string is "Proc-Type: 4 ~ BADMY\ n"

In fact, although there is a MIC (summary of information) option in the field information above, openssl's PEM library does not implement MIC computing. Of course, the data information of PEM can be summarized by using a series of RSA-MD functions and the result can be used as the MIC of PEM. You can generate MIC-info header information through the PEM_dek_info function and write it to the PEM structure, but according to openssl, this may take a long time, about 5 minutes.

4.2 PEM_dek_info

Similar to the above function, this function generates the information of the DEK-info field based on the type parameter, returns it and writes it to the buf. The parameter str should provide the value of the ivec variable, and the parameter len is the length of the str (in bytes). Here, the parameter type should be the name of the encryption algorithm. In principle, the string can be arbitrary, but in order for other programs to interpret the field correctly, you can first get the corresponding NID of the algorithm, and then call nid2sn to get the abbreviation of the algorithm as the type parameter. For example, if we need to use the algorithm structure enc in PEM_ASN1_write_bio, we can call the following function:

Objstr=OBJ_nid2sn (EVP_CIPHER_nid (enc))

At this point, objstr is a string containing the abbreviation of the algorithm enc. We can then use this string in the PEM_dek_info function with the following statement:

PEM_dek_info (buf,objstr,8, (char *) iv)

4.3 PEM_do_header

This function is not as its name implies, but it actually does the decryption of a PEM-encoded object (if the PEM object needs to be decrypted), which is usually called by PEM_read_bio. Before calling this function, some header information of the PEM file should have been obtained so that the decryption operation can be done correctly. Among them, the information of the DEK-info field should be handled correctly before calling this function, so that the corresponding EVP_CIPHER structure information and IV variable can be obtained through the name and ivec of the field, which can be used as the cipher parameter of this function.

If the PEM file does not have a DEK-info field, the function simply returns 1, and the operation is successful because no decryption operation is required. If not, the function needs a password to decrypt it. First, it tries to get the password from the callback parameter (a callback function). The format of the callback function is as follows:

Callback (buffer, blen, verify)

Parameter buffer is where the return password is saved, blen is the maximum length of buffer, and verify parameter indicates whether password authentication is required (that is, the user is required to enter the same password twice). The default is 0.

If the callback parameter is NULL and the u parameter is not NULL, then the u parameter will be written to buffer with a string with the Terminator NULL as a password; if both the callback and u parameters are NULL, the default callback function will be called (for the specific meaning of u, please refer to "PEM Series 3 of openssl"). After the PEM_do_header function gets the password, it uses the password (including the length information) to decrypt the data together with the ivec variable of the cipher parameter type. The decrypted data is saved in data, and the length information is saved in plen. The function operation returns 1 successfully, otherwise 0 is returned.

4.4 PEM_get_EVP_CIPHER_INFO

This function is also generally called by the PEM_read_bio function. Before calling this function, the Proc-Type header information of PEM should have been read into the header parameter as clear text. If header is NULL, the function successfully returns 1 because there is no header information to process. If it is not NULL, the function first determines whether the header information begins with "Proc-Type:4,ENCRYPTED". If it is otherwise, the function returns 0 and does not process it. After that, the function starts to read the information of the DEK-info field, and then the function obtains an EVP_CIPHER structure using EVP_get_cihperbyname through the encryption algorithm name of the field and stores it in the parameter cipher- > cipher; then the function gets the value of ivec by calling the internal function and stores it in cipher- > iv. A successful operation returns 1, otherwise 0 is returned.

It is important to note that because this function calls EVP_get_cipherbyname, you should call EVP_add_cipher and EVP_add_alias, or SSLeay_add_all_algorithms, before calling this function to load information about all encryption algorithms into the program. For details, please refer to the relevant chapter of "EVP Series of openssl".

5.PEM message Encapsulation encryption Series function

This series of functions complete the encryption and coding of PEM objects and related keys and IV vectors to facilitate data preservation and transmission, including the following functions (openssl\ pem.h):

Int PEM_SealInit (PEM_ENCODE_SEAL_CTX * ctx, EVP_CIPHER * type,EVP_MD * md_type, unsigned char * * ek, int * ekl,unsigned char * iv, EVP_PKEY * * pubk, int npubk)

Void PEM_SealUpdate (PEM_ENCODE_SEAL_CTX * ctx, unsigned char * out, int * outl,unsigned char * in, int inl)

Int PEM_SealFinal (PEM_ENCODE_SEAL_CTX * ctx, unsigned char * sig,int * sigl,unsigned char * out, int * outl, EVP_PKEY * priv)

Void PEM_SignInit (EVP_MD_CTX * ctx, EVP_MD * type)

Void PEM_SignUpdate (EVP_MD_CTX * ctx,unsigned char * dje unsigned int cnt)

Int PEM_SignFinal (EVP_MD_CTX * ctx, unsigned char * sigret,unsigned int * siglen, EVP_PKEY * pkey)

Void ERR_load_PEM_strings ()

Among them, PEM_Seal* series functions complete the encryption and coding of PEM objects, keys and IV variables, and PEM_Sign series functions complete the digital signature of PEM.

5.1 PEM_SealInit function

This function initializes the subsequent PEM_SealUpdate and PEM_SealFinal functions. First, the function calls the function EVP_SignInit with the parameter md_type to initialize the information summary structure ctx- > md. Then, the function finds the corresponding EVP_CIPHER structure through the parameter type, generates the key and ivec variables suitable for the algorithm and saves them in the algorithm structure, and then uses the public key of the parameter pubk to call the function EVP_SealInit to encrypt the key. The encrypted key is stored in the parameter ek and its length is saved in ekl. The data is encoded by BASE64 after calling the EVP_EncodeUpdate function. Because the key and IV are already stored in ctx- > cipher, they can be used by subsequent functions to encrypt the PEM object. The function returns a positive value after a successful operation, otherwise it returns 0 or-1.

It should be noted that because this function also uses the encryption algorithm name lookup algorithm structure, the static algorithm structure stack must be loaded before calling this function.

5.2 PEM_SealUpdate function

This function is used to encrypt and encode the information body of the PEM object. The encryption key used is generated by the PEM_SealInit function. This function encrypts the inl-byte data in the parameter in using the symmetric encryption algorithm structure provided by ctx- > cipher (which already contains the key and IV), and then calls EVP_EncodeUpdate for BASE64 coding and saves it in the parameter out. Outl is the length information of the valid data in the out. At the same time, the function also calls the function EVP_SignUpdate function to summarize the data in the parameter in using the summary algorithm structure of ctx- > md, but there is no output for the time being, and so on when the PEM_SealFinal function is called.

It should be noted that the length of the input information in is limited to no more than 1200 bytes, otherwise more than 1200 bytes of information will be simply discarded.

5.3 PEM_SealFinal function

This function completes the operation of the entire PEM_Seal series. First of all, it completes the symmetric encryption of the data previously processed by the PEM_SealUpdate function, and encodes the data in BASE64 and outputs it to the parameter out,outl to preserve the effective length of the out data. At the same time, the function also completes the information summary and uses the private key of the parameter priv to sign (encrypt) the information. The result is encoded by BASE64 and output to the length information that the parameter sig,sigl is sig valid data. The function returns 1 for successful operation, otherwise 0 for successful operation.

It is important to note that after the function is run, the ctx- > md and ctx- > cipher structures are cleared, so if you want to save the key and IV used by the symmetric encryption algorithm, you need to save a backup before calling this function. Of course, this is not normally done, because these keys are supposed to be temporary keys that are only used to encrypt a message.

5.4 PEM_Seal Operation Summary

After completing the operations of the above three functions, you get the encrypted key, IV (from the PEM_SealInit function), and the body of the PEM object, all of which are encoded by BASE64. You can then send this information to the recipient. After receiving this information, the other party can decrypt and verify the data correctly by using his own private key and your public key.

5.5 PEM_SignInit,PEM_SignUpdate and PEM_SignFinal functions

These three functions perform the same function as the EVP_Sign series functions. In fact, the first two functions simply call the EVP_SignInit and EVP_SignUpdate functions. After PEM_SignFinal calls the EVP_SignFinal function to complete the information summary and signature (using the private key of the parameter pkey), it calls EVP_EncodeBlock to encode the signature information in BASE64, and then saves the encoded signature information in the parameter sigret,siglen to save the length of the sigret valid data. The PEM_SignFinal function returns 1 successfully, otherwise it returns 0.

5.6 ERR_load_PEM_strings function

This function initializes the error handling library with the error code information from the PEM library, which must be called before using any PEM series function.

6.PEM underlying IO function

PEM provides a series of underlying IO functions for data read and write operations. The IO functions of PEM objects described in later chapters are macro definitions of these functions, so although generally do not call these functions directly, it is necessary to have a clear understanding. These functions are defined as follows (openssl\ pem.h):

Int PEM_read_bio (BIO * bp, char * name, char * header,unsigned char * * data,long * len)

Int PEM_write_bio (BIO * bp,const char * name,char * hdr,unsigned char * data,long len)

Int PEM_bytes_read_bio (unsigned char * * pdata, long * plen, char * * pnm, const char * name, BIO * bp,pem_password_cb * cb, void * u)

Char * PEM_ASN1_read_bio (char * (* d2i) (), const char * name,BIO * bp,char * * x Magazine passwordpassport cb * cb, void * u)

Int PEM_ASN1_write_bio (int (* i2d) (), const char * name,BIO * bp,char * x Magi Const EVP_CIPHER * enc,unsigned char * kstr,int klen,pem_password_cb * cb, void * u)

STACK_OF (X509_INFO) * PEM_X509_INFO_read_bio (BIO * bp, STACK_OF (X509_INFO) * sk, pem_password_cb * cb, void * u)

Int PEM_X509_INFO_write_bio (BIO * bp,X509_INFO * xi, EVP_CIPHER * enc,unsigned char * kstr, int klen, pem_password_cb * cd, void * u)

Int PEM_read (FILE * fp, char * name, char * header,unsigned char * * data,long * len)

Int PEM_write (FILE * fp,char * name,char * hdr,unsigned char * data,long len)

Char * PEM_ASN1_read (char * (* d2i) (), const char * name,FILE * fp,char * * x Magazine passwordpassport cb * cb, void * u)

Int PEM_ASN1_write (int (* i2d) (), const char * name,FILE * fp,char * x Magi Const EVP_CIPHER * enc,unsigned char * kstr,int klen,pem_password_cb * callback, void * u)

STACK_OF (X509_INFO) * PEM_X509_INFO_read (FILE * fp, STACK_OF (X509_INFO) * sk,pem_password_cb * cb, void * u)

As you can see, many of these functions are described in part 3 and will not be covered in detail here.

6.1 PEM_read function

This function reads a PEM-encoded message from the file fp. This function saves the characters after the BEIGIN in the file as the object name in the parameter name; all the information between the line of BEGIN and the next blank line is read into the parameter header, if there is no information between them, set header to NULL; and then BASE64 decoding the information body into the data parameter, where len is the valid data length of the data parameter. The function returns 1 for success and 0 for failure.

6.2 PEM_read_bio function

This function does the same thing as PEM_read, except that the read object is BIO. In fact, PEM_read accomplishes its function by calling this function. The function returns 1 for success and 0 for failure.

6.3 PEM_write function

This function puts the data of the name parameter after the begin header and writes it to the fp file; then writes the parameter hdr information to the file, followed by a blank line; finally, it encodes the data of the data parameter len bytes into the file, writes it to the file, and finally adds the END header information to return the length of the PEM information body. Failure returns 0.

6.4 PEM_write_bio function

This function is the same as the PEM_write function, except that the Operand is BIO. In fact, the PEM_write function is called to complete its function. The length of the PEM message body is returned for success and 0 for failure.

6.5 PEM_ASN1_read function

This function first calls the PEM_read function to read the object information encoded by PEM, and then calls the PEM_get_EVP_CIPHER_INFO function to process the DEK-info field information in the PEM format to determine the encryption algorithm and iVector value of the information. The PEM message is encrypted, then call the PEM_do_header function to decrypt the message body (see part 4), and then call the d2i function to decode it for DER and convert it to an internally defined type, which is stored in the x parameter. A pointer to x is returned successfully, otherwise NULL is returned.

Note that the parameter name must be the PEM file data after the BEIGIN header. Because the function calls the PEM_get_EVP_CIPHER_INFO function, in order for the function to execute successfully, the algorithm must be loaded before calling this function. Although virtually any type of data can be encrypted, generally only the RSA private key needs to be encrypted. This function can read some column objects from a file.

6.6 PEM_ASN1_read_bio function

This function is the same as the PEM_ASN1_read function, except that the Operand is BIO. In fact, the PEM_ASN1_read function calls this function to complete its function. A pointer to x is returned successfully, otherwise NULL is returned.

6.7 PEM_ASN1_write function

This function converts object x to DER-encoded data using the function provided by the i2d parameter, and then encrypts the data using enc's encryption algorithm if the enc parameter is not NULL. The parameter kstr is used to generate the encryption key, and klen is the valid length of the kstr. If enc is not NULL, but kstr is NULL, then the callback function will be used to prompt the user for a password and get encrypted data; if callback is NULL, but u is not NULL, then u is used as the string to generate the encryption key, assuming that u should be the string ending with NULL; if both callback and u are NULL, the default callback function will be used to obtain the password. The data is then BASE64 encoded and written to the fp file, plus the BEIGIN start header information, END end header information, Type-Proc field, and DEK-info field (if the data is encrypted). The encryption key is cleared after the function call. A successful operation returns 1, otherwise 0 is returned.

6.8 PEM_ASN1_wirte_bio function

This function implements the same function as PEM_ASN1_write, except that the Operand is BIO. In fact, the PEM_ASN1_write function calls this function to complete its function. A successful operation returns 1, otherwise 0 is returned.

6.9 PEM_X509_INFO_read function

This function performs the same function as PEM_ASN1_read, except that it automatically calls the corresponding d2i series functions based on the BEGIN header information, and currently supports types d2i_X509, d2i_X509_AUX, d2i_X509_CRL, d2i_RSAPrivateKey and d2i_DSAPrivateKey. This function processes all objects in the file until an error or processing is completed. All processed objects are stored in the stack sk. Because it is possible that some objects are encrypted, the parameters cb and u are provided. The meaning of parameters cb and u is referred to part 3. Returns the processed stack pointer successfully, otherwise returns NULL.

6.10 PEM_X509_INFO_read_bio function

This function performs the same function as the PEM_X509_INFO_read function, except that the Operand is BIO. In fact, the PEM_X509_INFO_read function calls this function to complete its function. Returns the processed stack pointer successfully, otherwise returns NULL.

6.11 PEM_X509_INFO_write_bio function

This function performs the same function as PEM_ASN1_write_bio. In addition to reading each part of the object from the parameter xi, use the parameters xi- > x_pkey and xi- > x509 respectively and use the corresponding i2d function to PEM into independent information, which is written to the bio. Similarly, the user may be required to enter a password to generate an encryption key, and the related parameters cb, enc, kstr, klen, and u refer to the previous function and part 3 for meaning. The function returns 1 successfully, otherwise 0.

7.PEM object read and write IO function (1)

Basically, openssl provides IO functions for reading and writing in PEM format for each object it defines. In this sense, the PEM format is just BASE64-encoded data that contains header information. These functions are basically based on the functions introduced in part 6, that is, most of them are just macro definitions of these functions. Because we have introduced the general parameters of PEM series functions in detail in part 3, this article will not explain these general parameters in detail.

For each object, openssl generally provides four functions, such as an object named Name. The four function names provided are as follows:

PEM_read_bio_Name ()

PEM_read_Name ()

PEM_write_bio_Name ()

PEM_write_Name ()

As you can see, there are two read operation functions and two write operation functions. Among them, two read operation functions or two write operation functions are the same, but the object is a file handle and the other is BIO. In addition, the read function of all objects returns the pointer of the corresponding object if the operation is successful, otherwise it returns NULL;, while the write function returns a non-zero value for successful operation and 0 for failure. Let's give a brief introduction to these functions.

7.1 IO of the private key object PrivateKey

EVP_PKEY * PEM_read_bio_PrivateKey (BIO * bp, EVP_PKEY * * x pemetics passwordkeeper cb * cb, void * u)

EVP_PKEY * PEM_read_PrivateKey (FILE * fp, EVP_PKEY * * x pemetics passwordkeeper cb * cb, void * u)

Int PEM_write_bio_PrivateKey (BIO * bp, EVP_PKEY * x, const EVP_CIPHER * enc,unsigned char * kstr, int klen,pem_password_cb * cb, void * u)

Int PEM_write_PrivateKey (FILE * fp, EVP_PKEY * x, const EVP_CIPHER * enc,unsigned char * kstr, int klen,pem_password_cb * cb, void * u)

These functions read and write the private key of an EVP_PKEY structure in PEM format. The write function can handle private keys of type RSA or DSA. The read operation function can also transparently handle private keys encrypted and decrypted in PKCS#8 format.

1. An example of writing an unencrypted private key to a file

If (! PEM_write_PrivateKey (fp, key, NULL, NULL, 0,0, NULL))

{

/ * error handling code * /

}

two。 Write a private key to BIO, encrypt it with 3DES, and prompt for an encrypted password.

If (! PEM_write_bio_PrivateKey (bp, key, EVP_des_ede3_cbc (), NULL, 0,0, NULL))

{

/ * error handling code * /

}

3. Reread a private key from BIO and use "hello" as an example of a decryption password

Key = PEM_read_bio_PrivateKey (bp, NULL, 0, "hello")

If (key = = NULL)

{

/ * error handling code * /

}

4. An example of reading a private key from BIO and using a callback function to obtain a decryption password

Key = PEM_read_bio_PrivateKey (bp, NULL, pass_cb, "My PrivateKey")

If (key = = NULL)

{

/ * error handling code * /

}

Reading and writing IO functions for 8.PEM objects (2)

This article continues to introduce the read and write IO function of the PEM object, see part 7 for a better understanding of this article.

8.1 IO of the private key object PKCS8PrivateKey that conforms to PKCS#8 and PKCS#5 v2.0 standards

Int PEM_write_bio_PKCS8PrivateKey (BIO * bp, EVP_PKEY * x, const EVP_CIPHER * enc,char * kstr, int klen,pem_password_cb * cb, void * u)

Int PEM_write_PKCS8PrivateKey (FILE * fp, EVP_PKEY * x, const EVP_CIPHER * enc,char * kstr, int klen,pem_password_cb * cb, void * u)

These two functions use the PKCS#8 standard to save the private key in EVP_PKEY to a file or BIO, and encrypt the private key using the PKCS#5 v2.0 standard. The enc parameter defines the encryption algorithm used. Unlike other PEM IO functions, the encryption of this function is based on the PKCS#8 level, not on the PEM information field, so these two functions are also implemented separately, rather than macro-defined functions. If the enc parameter is NULL, then no encryption operation is performed, only the PKCS#8 private key information structure is used. Successful execution returns a number greater than 0, otherwise 0 is returned.

PEM objects saved using these two functions can be read using the PEM_read_bio_PrivateKey or PEM_read_PrivateKey introduced in the previous article.

The following is an example of saving the private key in PKCS#8 format and encrypting it using the 3DES algorithm with a password of "hello"

If (! PEM_write_bio_PKCS8PrivateKey (bp, key, EVP_des_ede3_cbc (), NULL, 0,0, "hello"))

{

/ * error handling code * /

}

8.2 IO of private key object PKCS8PrivateKey that conforms to PKCS#8 and PKCS#5 v1.5 or PKCS#12 standards

Int PEM_write_bio_PKCS8PrivateKey_nid (BIO * bp, EVP_PKEY * x, int nid,char * kstr, int klen,pem_password_cb * cb, void * u)

Int PEM_write_PKCS8PrivateKey_nid (FILE * fp, EVP_PKEY * x, int nid,char * kstr, int klen,pem_password_cb * cb, void * u)

These two functions are also implemented separately, rather than macro-defined functions. They also save the private key in PKCS#8 format, but use PKCS#5 v1.5 or PKCS#12 to encrypt the private key. The nid parameter specifies the corresponding encryption algorithm, whose value should be the NID of the corresponding object. Successful execution returns a number greater than 0, otherwise 0 is returned.

PEM objects saved using these two functions can be read using the PEM_read_bio_PrivateKey or PEM_read_PrivateKey introduced in the previous article.

8.3 IO of the public key object PUBKEY

EVP_PKEY * PEM_read_bio_PUBKEY (BIO * bp, EVP_PKEY * * x pemetics passwordkeeper cb * cb, void * u)

EVP_PKEY * PEM_read_PUBKEY (FILE * fp, EVP_PKEY * * x pemetics passwordkeeper cb * cb, void * u)

Int PEM_write_bio_PUBKEY (BIO * bp, EVP_PKEY * x)

Int PEM_write_PUBKEY (FILE * fp, EVP_PKEY * x)

These four functions read and write the public key of the EVP_PKEY structure in PEM format. The public key is encoded as a SubjectPublicKeyInfo storage structure.

8.4 IO of the RSA private key object RSAPrivateKey

RSA * PEM_read_bio_RSAPrivateKey (BIO * bp, RSA * * x pemetics passwordkeeper cb * cb, void * u)

RSA * PEM_read_RSAPrivateKey (FILE * fp, RSA * * x pemetics passwordkeeper cb * cb, void * u)

Int PEM_write_bio_RSAPrivateKey (BIO * bp, RSA * x, const EVP_CIPHER * enc,unsigned char * kstr, int klen,pem_password_cb * cb, void * u)

Int PEM_write_RSAPrivateKey (FILE * fp, RSA * x, const EVP_CIPHER * enc,unsigned char * kstr, int klen,pem_password_cb * cb, void * u)

These four functions read and write the RSA private key of RSA structure in PEM format. It uses the same function as PrivateKey for processing, but returns an error message if the private key type is not RSA.

8.5 IO of the RSA public key object RSAPublicKey

RSA * PEM_read_bio_RSAPublicKey (BIO * bp, RSA * * x pemetics passwordkeeper cb * cb, void * u)

RSA * PEM_read_RSAPublicKey (FILE * fp, RSA * * x pemetics passwordkeeper cb * cb, void * u)

Int PEM_write_bio_RSAPublicKey (BIO * bp, RSA * x)

Int PEM_write_RSAPublicKey (FILE * fp, RSA * x)

These four functions read and write the public key of the RSA structure in PEM format. This function uses the PKCS#1 RSAPublicKey structure standard to encode the RSA public key.

8.6 IO of the RSA public key object RSA_PUBKEY

RSA * PEM_read_bio_RSA_PUBKEY (BIO * bp, RSA * * x pemetics passwordkeeper cb * cb, void * u)

RSA * PEM_read_RSA_PUBKEY (FILE * fp, RSA * * x pemetics passwordkeeper cb * cb, void * u)

Int PEM_write_bio_RSA_PUBKEY (BIO * bp, RSA * x)

Int PEM_write_RSA_PUBKEY (FILE * fp, RSA * x)

These four functions are also used to read and write the public key of RSA structure in PEM format. However, this function uses the SubjectPublicKeyInfo structure standard to encode the RSA public key. If the public key type is not RSA, an error will be returned.

Reading and writing IO functions for 9.PEM objects (3)

This article continues to introduce the read and write IO functions of the PEM object, see parts 7 and 8 for a better understanding of this article.

9.1 IO function of the DSA private key object DSAPrivateKey

DSA * PEM_read_bio_DSAPrivateKey (BIO * bp, DSA * * x pemetics passwordkeeper cb * cb, void * u)

DSA * PEM_read_DSAPrivateKey (FILE * fp, DSA * * x pemetics passwordkeeper cb * cb, void * u)

Int PEM_write_bio_DSAPrivateKey (BIO * bp, DSA * x, const EVP_CIPHER * enc,unsigned char * kstr, int klen,pem_password_cb * cb, void * u)

Int PEM_write_DSAPrivateKey (FILE * fp, DSA * x, const EVP_CIPHER * enc,unsigned char * kstr, int klen,pem_password_cb * cb, void * u)

These functions perform IO read and write to the DSA private key stored in DSA structure in PEM format. They use the same processing format as the PrivateKey series functions, but an error is returned if the private key is not of type DSA.

9.2 IO function of the DSA public key object DSA_PUBKEY

DSA * PEM_read_bio_DSA_PUBKEY (BIO * bp, DSA * * x pemetics passwordkeeper cb * cb, void * u)

DSA * PEM_read_DSA_PUBKEY (FILE * fp, DSA * * x pemetics passwordkeeper cb * cb, void * u)

Int PEM_write_bio_DSA_PUBKEY (BIO * bp, DSA * x)

Int PEM_write_DSA_PUBKEY (FILE * fp, DSA * x)

These functions perform IO read and write to the DSA public key stored in DSA structure in PEM format. The public key is encoded in the SubjectPublicKeyInfo structure, and if the public key is not of type DSA, an error will be returned.

9.3 the IO function of the DSA parameter object DSAParams

DSA * PEM_read_bio_DSAparams (BIO * bp, DSA * * x, pem_password_cb * cb, void * u)

DSA * PEM_read_DSAparams (FILE * fp, DSA * * x, pem_password_cb * cb, void * u)

Int PEM_write_bio_DSAparams (BIO * bp, DSA * x)

Int PEM_write_DSAparams (FILE * fp, DSA * x)

These functions perform IO read and write operations on DSA parameters stored in DSA structure in PEM format.

9.4 the IO function of the DH parameter object DHParams

DH * PEM_read_bio_DHparams (BIO * bp, DH * * x, pem_password_cb * cb, void * u)

DH * PEM_read_DHparams (FILE * fp, DH * * x, pem_password_cb * cb, void * u)

Int PEM_write_bio_DHparams (BIO * bp, DH * x)

Int PEM_write_DHparams (FILE * fp, DH * x)

These functions perform IO read and write operations on the DH parameters saved in DH structure in PEM format, and these parameters are encoded by PKCS#3 's DH parameter structure.

9.5X509 Certificate object X509 IO function

X509 * PEM_read_bio_X509 (BIO * bp, X509 * * x, pem_password_cb * cb, void * u)

X509 * PEM_read_X509 (FILE * fp, X509 * * x, pem_password_cb * cb, void * u)

Int PEM_write_bio_X509 (BIO * bp, X509 * x)

Int PEM_write_X509 (FILE * fp, X509 * x)

These functions perform IO read and write operations on X509 certificates saved in X509 structure in PEM format. These functions can also do the same for trust X509 certificates, but the trust setting information is lost.

9.6X509 trust the IO function of the certificate object X509_AUX

X509 * PEM_read_bio_X509_AUX (BIO * bp, X509 * * x, pem_password_cb * cb, void * u)

X509 * PEM_read_X509_AUX (FILE * fp, X509 * * x, pem_password_cb * cb, void * u)

Int PEM_write_bio_X509_AUX (BIO * bp, X509 * x)

Int PEM_write_X509_AUX (FILE * fp, X509 * x)

These functions perform IO read and write operations on trust X509 certificates saved in X509 structure in PEM format.

9.7X509 IO function of Certificate request object X509_REQ

X509_REQ * PEM_read_bio_X509_REQ (BIO * bp, X509_REQ * * x pemetics passwordkeeper cb * cb, void * u)

X509_REQ * PEM_read_X509_REQ (FILE * fp, X509_REQ * * x pemetics passwordkeeper cb * cb, void * u)

Int PEM_write_bio_X509_REQ (BIO * bp, X509_REQ * x)

Int PEM_write_X509_REQ (FILE * fp, X509_REQ * x)

Int PEM_write_bio_X509_REQ_NEW (BIO * bp, X509_REQ * x)

Int PEM_write_X509_REQ_NEW (FILE * fp, X509_REQ * x)

These functions perform IO read and write operations on PKCS#10 standard-compliant certificate requests stored in X509_REQ structure in PEM format. The difference is that the X509_REQ series write functions use CERTIFICATE REQUEST as the header, while the X509_REQ_NEW series write functions use NEW CERTIFICATE REQUEST as the header (some CA require this format). The X509_REQ read function can handle both cases, so there is no read function for X509_REQ_NEW.

9.8X509 the IO function of the revocation list object X509_CRL

X509_CRL * PEM_read_bio_X509_CRL (BIO * bp, X509_CRL * * x pemetics passwordkeeper cb * cb, void * u)

X509_CRL * PEM_read_X509_CRL (FILE * fp, X509_CRL * * x pemetics passwordkeeper cb * cb, void * u)

Int PEM_write_bio_X509_CRL (BIO * bp, X509_CRL * x)

Int PEM_write_X509_CRL (FILE * fp, X509_CRL * x)

These functions perform IO read and write operations on X509 CRL stored in X509_CRL structure in PEM format.

9.9 IO function of PKCS7 encoded by PKCS#7 content object

PKCS7 * PEM_read_bio_PKCS7 (BIO * bp, PKCS7 * * x, pem_password_cb * cb, void * u)

PKCS7 * PEM_read_PKCS7 (FILE * fp, PKCS7 * * x, pem_password_cb * cb, void * u)

Int PEM_write_bio_PKCS7 (BIO * bp, PKCS7 * x)

Int PEM_write_PKCS7 (FILE * fp, PKCS7 * x)

These Hansen perform IO read and write operations on PKCS#7 content information stored in PKCS7 structure in PEM format.

9.10 IO function of Netscape Certificate sequence object NETSCAPE_CERT_SEQUENCE

NETSCAPE_CERT_SEQUENCE * PEM_read_bio_NETSCAPE_CERT_SEQUENCE (BIO * bp,NETSCAPE_CERT_SEQUENCE * * x Magneto pemetics passwordkeeper cb * cb, void * u)

NETSCAPE_CERT_SEQUENCE * PEM_read_NETSCAPE_CERT_SEQUENCE (FILE * fp,NETSCAPE_CERT_SEQUENCE * * x Magneto pemetics passwordkeeper cb * cb, void * u)

Int PEM_write_bio_NETSCAPE_CERT_SEQUENCE (BIO * bp, NETSCAPE_CERT_SEQUENCE * x)

Int PEM_write_NETSCAPE_CERT_SEQUENCE (FILE * fp, NETSCAPE_CERT_SEQUENCE * x)

These functions perform IO read and write operations on Netscape certificate sequences stored in NETSCAPE_CERT_SEQUENCE structure in PEM format.

10. Callback function example 10.1 example of getting password callback function

In the process of reading and writing PEM, especially for private key files, you may often use the callback function to obtain the password. In signing some of the functions we introduced, we can also see that basically all of them have callback function parameters. The default callback function of openssl is based on the command line and may not be suitable in many cases, which requires the user to define the callback function. In the previous relevant section, we have introduced the format of the callback function, and now we give an implementation example of the callback function.

Int pass_cb (char * buf, int size, int rwflag, void * u)

{

Int len

Char * tmp

/ * rwflag is a standard, if it is 1, some other processing work may need to be done * /

Printf ("enter password:\"% s\ "\ n", u)

/ * this should be the code to get the password * /

Tmp = "hello"

Len = strlen (tmp)

If (len size) len = size

Memcpy (buf, tmp, len)

Return len

}

10.2 A common mistake in using PEM series functions

The format and parameters of the PEM series of functions are basically the same, and here is a common use that leads to errors.

X509 * x

PEM_read_bio_X509 (bp, & x, 0, NULL)

This usage can lead to unpredictable errors because x is not initialized and memory space is allocated, while the next function will write data to x, resulting in illegal memory operations. This is also a BUG that openssl itself did not handle well.

Global trusted CA institutions

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report