Getting common name efficiently from tls certificate with openssl - c

I have a pointer to TLS certificate and I need to get commonName property;
I at first create X509 object with function d2i_X509 like ;
x = d2i_X509(NULL, &p, certificate_lenght);
if (x == NULL)
return https_failure;
Than I call function X509_NAME_get_text_by_NID for getting commonName
X509_NAME_get_text_by_NID(X509_get_subject_name(x),NID_commonName, hc->https_domain_name, 256);
It works for me but I am worried about performance . I think, all certificate object is parsed when I only need commonName . Is there any better method for getting commonName with more efficiency .

There is no more efficient way using OpenSSL high-level API. If you are really interested in having the best performance possible, you'll need to use the low-level ASN.1 parsing API.
But keep in mind that you cannot fully validate a certificate without parsing it entirely, so I would be concerned with the security implications of only extracting the CN.

Related

How much trust should I put in the validity of retrieved data from database?

Other way to ask my question is: "Should I keep the data types coming from database as simple and raw as I would ask them from my REST endpoint"
Imagine this case class that I want to store in the database as a row:
case class Product(id: UUID,name: String, price: BigInt)
It clearly isn't and shouldn't be what it says it is because The type signatures of nameand price are a lie.
so what we do is create custom data types that better represent what things are such as: (For the sake of simplicity imagine our only concern is the price data type)
case class Price(value: BigInt) {
require(value > BigInt(0))
}
object Price {
def validate(amount: BigInt): Either[String,Price] =
Try(Price(amount)).toOption.toRight("invalid.price")
}
//As a result my Product class is now:
case class Product(id: UUID,name: String,price: Price)
So now the process of taking user input for product data would look like this:
//this class would be parsed from i.e a form:
case class ProductInputData(name: String, price: BigInt)
def create(input: ProductInputData) = {
for {
validPrice <- Price.validate(input.price)
} yield productsRepo.insert(
Product(id = UUID.randomUUID,name = input.name,price = ???)
)
}
look at the triple question marks (???). this is my main point of concern from an entire application architecture perspective; If I had the ability to store a column as Price in the database (for example slick supports these custom data types) then that means I have the option to store the price as either price : BigInt = validPrice.value or price: Price = validPrice.
I see so many pros and cons in both of these decisions and I can't decide.
here are the arguments that I see supporting each choice:
Store data as simple database types (i.e. BigInt) because:
performance: simple assertion of x > 0 on the creation of Price is trivial but imagine you want to validate a Custom Email type with a complex regex. it would be detrimental upon retrieval of collections
Tolerance against Corruption: If BigInt is inserted as negative value it would't explode in your face every time your application tried to simply read the column and throw it out on to the user interface. It would however cause problem if it got retrieved and then involved in some domain layer processing such as purchase.
Store data as it's domain rich type (i.e. Price) because:
No implicit reasoning and trust: Other method some place else in the system would need the price to be valid. For example:
//two terrible variations of a calculateDiscount method:
//this version simply trusts that price is already valid and came from db:
def calculateDiscount(price: BigInt): BigInt = {
//apply some positive coefficient to price and hopefully get a positive
//number from it and if it's not positive because price is not positive then
//it'll explode in your face.
}
//this version is even worse. It does retain function totality and purity
//but the unforgivable culture it encourages is the kind of defensive and
//pranoid programming that causes every developer to write some guard
//expressions performing duplicated validation All over!
def calculateDiscount(price: BigInt): Option[BigInt] = {
if (price <= BigInt(0))
None
else
Some{
//Do safe processing
}
}
//ideally you want it to look like this:
def calculateDiscount(price: Price): Price
No Constant conversion of domain types to simple types and vice versa: for representation, storage,domain layer and such; you simply have one representation in the system to rule them all.
The source of all this mess that I see is the database. if data was coming from the user it'd be easy: You simply never trust it to be valid. you ask for simple data types cast them to domain types with validation and then proceed. But not the db. Does the modern layered architecture address this issue in some definitive or at least mitigating way?
Protect the integrity of the database. Just as you would protect the integrity of the internal state of an object.
Trust the database. It doesn't make sense to check and re-check what has already been checked going in.
Use domain objects for as long as you can. Wait till the very last moment to give them up (raw JDBC code or right before the data is rendered).
Don't tolerate corrupt data. If the data is corrupt, the application should crash. Otherwise it's likely to produce more corrupt data.
The overhead of the require call when retrieving from the DB is negligible. If you really think it's an issue, provide 2 constructors, one for the data coming from the user (performs validation) and one that assumes the data is good (meant to be used by the database code).
I love exceptions when they point to a bug (data corruption because of insufficient validation on the way in).
That said, I regularly leave requires in code to help catch bugs in more complex validation (maybe data coming from multiple tables combined in some invalid way). The system still crashes (as it should), but I get a better error message.

how to calculate MD5 hash and HMAC-SHA1 in c

I have to prepare Message Integrity Attribute for TURN allocation request.
say my username is user_1, realm is 192.168.1.101 and password is user_pass_1
key = MD5(user_1:192.168.1.101:user_pass_1)
then I have to perform HMAC-SHA1 on a buffer using above key.
I want to use gnutls library for calculating HMAC-SHA1, is there any way to do it

Log users into eXist-db using MD5 password (XQuery)

I need to log users into eXist-db using XQuery. Of course I can use this code:
xquery version "3.0";
declare namespace exist = "http://exist.sourceforge.net/NS/exist";
declare namespace request="http://exist-db.org/xquery/request";
declare namespace xmldb="http://exist-db.org/xquery/xmldb";
declare option exist:serialize "method=json media-type=text/javascript";
let $userName := request:get-parameter("userName", ())
let $hash := request:get-parameter("hash", ())
let $login := xmldb:authenticate('/db', $userName, $hash)
return
<ajax-response>
<success>{$login}</success>
<username>{$userName}</username>
</ajax-response>
The problem is that, due to the fact that I receive the password and the username from another service, I receive them in hash form encrypted with MD5 (because they can't be passed in clear from a service to another).
But the xmldb:authenticate function needs the password in clear. How can I resolve this? Any idea? Is there a way to login 'manually' in eXist-db without using the authenticate function?
No, this is not possible: eXist-db does not work with hashes on the authentication functions, that would be a security risk since MD5 is not safe. In addition, eXist-db does not use MD5 internally for hashing the passwords, so validating a password would be difficult (matching two different hashing techniques is impossible)
Unfortunately there is no way to work around this with the standard functions.

what are the rules that apply on the key_name in app engine?

I'm trying to use an app engine User object's user_id (returned by the User.user_id() method) as a key_name in my own User class. The problem is that it keeps telling me that it's an invalid key_name. I've tried sha2'ing it, and using the digest() as well as the hexdigest() method to reduce the number of possible characters, but still no good result. Is this because the value is too long, or because key names can't have certain characters? And also, how can I modify a user_id in such a way that it stays unique, but is also usable as a key_name for an entity? Extra bonus if it uses a hash so that thje user_id can't be guessed.
Here is the code where the error occured:
def get_current_user():
return User.get(db.Key(hashlib.sha1(users.get_current_user().user_id()).hexdigest()))
I'm now doing some more testing, concidering suggestions from the comments and answer.
I'm not sure why it isn't working for you, the following has no issues when I run it in the dev console.
from google.appengine.ext import db
from google.appengine.api import users
user = users.get_current_user()
name = user.user_id()
print db.Key.from_path ('User', name)
However if you are hashing it (which it sounds like you may be), be aware that you may get a collision. I would avoid against using a hash and would consider some other means of anonymization if you are giving the key to clients. Such as another model whose key you can give away, that has the user's key stored in it. Another method would be to encrypt the id (using the same key for all users) rather than hash it.
If you are doing something that generates binary data (encryption / hash digest) app engine (the sdk at-least) has issues, so you need to encode it first, and use that as the key_name.
name = user.user_id()
hashed_name = hashlib.sha1(name).digest()
encoded_name = base64.b64encode (name)
db.Key.from_path ('User', encoded_name)

Check if the file is correct using sha1withRsa via openssl functions

Hi, i have file_data(xml format) and file_signature(ASN1 DER), and also have certificate(X509 ASN1 DER). I want to check if file_data is correct, but I have some problems. what I'm doing:
Main Idea: Some company A creates file_data, then using SHA1 gets hash of the file_data, and encrypts this hash using RSA private key and gets file_signature. Then company A sends me file_data and file_signature and certificate. I get public key from certificate get file_signature and decrypt file_signature using public key and get hash_1. Then i get file_data and use SHA1 to get hash_2. If hash_1 and hash_2 is equal, i can trust to content of the file_data, am I right?
Implementation:
Load certificate: d2i_X509_fp() function. Now I have certificate.
Get public key of the certificate: X509_extract_key, now i have public key.
Now i want to load file_signature to decrypt it using public key, BUT file_signature has ASN1 DER format how I can load it, what function in OpenSSl should I use?
Suppose I read file_signature, now I must decrypt it using my public key, is there any API for this purpose?
Suppose I decrypt file_signature and get hash_1.
Now I must load file_data and get hash of it using SHA1 function hash_2, what function I must use? SHA1(), or SHA1_Init, SHA1_Update, SHA1_Finish?
Suppose I get hash_1 and hash_2, how i must compare them, using memcmp?
Suppose I compare them, if they are equal, i can use file_data.
another question is that file_signature is 128 byte len and when i decrypt it i get 128 byte hash_1(Am I rigth) , but when i get hash of the file_data hash_2 it's length is only 20 bytes, so how I can compare them, or I misunderstand something?
Thanks for your help!
p.s. sorry for my english;).
If you get a file_signature of 128 bytes, then it is probably not ASN.1 encoded. 128 bits is exactly the key length of a 1024 bit key (on the low side nowadays, check keylength.com). Hashes are not directly encrypted if RSA is used: first it is wrapped within an ASN.1 structure, and then it is padded, all according to PKCS#1 v1.5 (Google it).
Normally you don't perform the hashing separately from the RSA encrypt. Libraries like openssl will contain functions to perform verification where the hash is automatically calculated (no doubt this would be openssl_verify()). Those functions will also do the compare for you.
Note that you will need to establish trust for the public key, otherwise an attacker could just generate a random key pair and send you a different public key together with the attackers signed data. Normally public keys are trusted using direct communication beforehand, or using a PKI infrastructure (certificate chains).

Resources